plotly.js 2.6.2 → 2.6.3
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/CHANGELOG.md +7 -0
- package/README.md +3 -3
- package/dist/README.md +19 -19
- package/dist/plotly-basic.js +85 -78
- package/dist/plotly-basic.min.js +2 -2
- package/dist/plotly-cartesian.js +85 -78
- package/dist/plotly-cartesian.min.js +2 -2
- package/dist/plotly-finance.js +85 -78
- package/dist/plotly-finance.min.js +2 -2
- package/dist/plotly-geo-assets.js +2 -2
- package/dist/plotly-geo.js +85 -78
- package/dist/plotly-geo.min.js +4 -4
- package/dist/plotly-gl2d.js +85 -78
- package/dist/plotly-gl2d.min.js +2 -2
- package/dist/plotly-gl3d.js +85 -78
- package/dist/plotly-gl3d.min.js +8 -8
- package/dist/plotly-mapbox.js +85 -78
- package/dist/plotly-mapbox.min.js +2 -2
- package/dist/plotly-strict.js +85 -78
- package/dist/plotly-strict.min.js +2 -2
- package/dist/plotly-with-meta.js +85 -78
- package/dist/plotly.js +85 -78
- package/dist/plotly.min.js +2 -2
- package/package.json +1 -1
- package/src/components/colorbar/draw.js +72 -61
- package/src/components/fx/hover.js +11 -15
- package/src/version.js +1 -1
package/dist/plotly-cartesian.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* plotly.js (cartesian) v2.6.
|
|
2
|
+
* plotly.js (cartesian) v2.6.3
|
|
3
3
|
* Copyright 2012-2021, Plotly, Inc.
|
|
4
4
|
* All rights reserved.
|
|
5
5
|
* Licensed under the MIT license
|
|
@@ -31122,6 +31122,19 @@ function makeColorBarData(gd) {
|
|
|
31122
31122
|
}
|
|
31123
31123
|
|
|
31124
31124
|
function drawColorBar(g, opts, gd) {
|
|
31125
|
+
var len = opts.len;
|
|
31126
|
+
var lenmode = opts.lenmode;
|
|
31127
|
+
var thickness = opts.thickness;
|
|
31128
|
+
var thicknessmode = opts.thicknessmode;
|
|
31129
|
+
var outlinewidth = opts.outlinewidth;
|
|
31130
|
+
var borderwidth = opts.borderwidth;
|
|
31131
|
+
var xanchor = opts.xanchor;
|
|
31132
|
+
var yanchor = opts.yanchor;
|
|
31133
|
+
var xpad = opts.xpad;
|
|
31134
|
+
var ypad = opts.ypad;
|
|
31135
|
+
var optsX = opts.x;
|
|
31136
|
+
var optsY = opts.y;
|
|
31137
|
+
|
|
31125
31138
|
var fullLayout = gd._fullLayout;
|
|
31126
31139
|
var gs = fullLayout._size;
|
|
31127
31140
|
|
|
@@ -31151,42 +31164,41 @@ function drawColorBar(g, opts, gd) {
|
|
|
31151
31164
|
// when the colorbar itself is pushing the margins.
|
|
31152
31165
|
// but then the fractional size is calculated based on the
|
|
31153
31166
|
// actual graph size, so that the axes will size correctly.
|
|
31154
|
-
var thickPx = Math.round(
|
|
31167
|
+
var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? gs.w : 1));
|
|
31155
31168
|
var thickFrac = thickPx / gs.w;
|
|
31156
|
-
var lenPx = Math.round(
|
|
31169
|
+
var lenPx = Math.round(len * (lenmode === 'fraction' ? gs.h : 1));
|
|
31157
31170
|
var lenFrac = lenPx / gs.h;
|
|
31158
|
-
var xpadFrac =
|
|
31159
|
-
var yExtraPx = (
|
|
31160
|
-
var ypadFrac =
|
|
31171
|
+
var xpadFrac = xpad / gs.w;
|
|
31172
|
+
var yExtraPx = (borderwidth + outlinewidth) / 2;
|
|
31173
|
+
var ypadFrac = ypad / gs.h;
|
|
31161
31174
|
|
|
31162
31175
|
// x positioning: do it initially just for left anchor,
|
|
31163
31176
|
// then fix at the end (since we don't know the width yet)
|
|
31164
|
-
var
|
|
31177
|
+
var uPx = Math.round(optsX * gs.w + xpad);
|
|
31165
31178
|
// for dragging... this is getting a little muddled...
|
|
31166
|
-
var
|
|
31179
|
+
var uFrac = optsX - thickFrac * ({center: 0.5, right: 1}[xanchor] || 0);
|
|
31167
31180
|
|
|
31168
31181
|
// y positioning we can do correctly from the start
|
|
31169
|
-
var
|
|
31170
|
-
var
|
|
31171
|
-
var yTopPx = yBottomPx - lenPx;
|
|
31182
|
+
var vFrac = optsY + lenFrac * (({top: -0.5, bottom: 0.5}[yanchor] || 0) - 0.5);
|
|
31183
|
+
var vPx = Math.round(gs.h * (1 - vFrac));
|
|
31172
31184
|
|
|
31173
31185
|
// stash a few things for makeEditable
|
|
31174
31186
|
opts._lenFrac = lenFrac;
|
|
31175
31187
|
opts._thickFrac = thickFrac;
|
|
31176
|
-
opts.
|
|
31177
|
-
opts.
|
|
31188
|
+
opts._uFrac = uFrac;
|
|
31189
|
+
opts._vFrac = vFrac;
|
|
31178
31190
|
|
|
31179
31191
|
// stash mocked axis for contour label formatting
|
|
31180
31192
|
var ax = opts._axis = mockColorBarAxis(gd, opts, zrange);
|
|
31181
31193
|
|
|
31182
31194
|
// position can't go in through supplyDefaults
|
|
31183
31195
|
// because that restricts it to [0,1]
|
|
31184
|
-
ax.position =
|
|
31196
|
+
ax.position = optsX + xpadFrac + thickFrac;
|
|
31185
31197
|
|
|
31186
31198
|
if(['top', 'bottom'].indexOf(titleSide) !== -1) {
|
|
31187
31199
|
ax.title.side = titleSide;
|
|
31188
|
-
ax.titlex =
|
|
31189
|
-
ax.titley =
|
|
31200
|
+
ax.titlex = optsX + xpadFrac;
|
|
31201
|
+
ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
|
|
31190
31202
|
}
|
|
31191
31203
|
|
|
31192
31204
|
if(line.color && opts.tickmode === 'auto') {
|
|
@@ -31194,7 +31206,7 @@ function drawColorBar(g, opts, gd) {
|
|
|
31194
31206
|
ax.tick0 = levelsIn.start;
|
|
31195
31207
|
var dtick = levelsIn.size;
|
|
31196
31208
|
// expand if too many contours, so we don't get too many ticks
|
|
31197
|
-
var autoNtick = Lib.constrain(
|
|
31209
|
+
var autoNtick = Lib.constrain(lenPx / 50, 4, 15) + 1;
|
|
31198
31210
|
var dtFactor = (zrange[1] - zrange[0]) / ((opts.nticks || autoNtick) * dtick);
|
|
31199
31211
|
if(dtFactor > 1) {
|
|
31200
31212
|
var dtexp = Math.pow(10, Math.floor(Math.log(dtFactor) / Math.LN10));
|
|
@@ -31212,8 +31224,8 @@ function drawColorBar(g, opts, gd) {
|
|
|
31212
31224
|
// set domain after init, because we may want to
|
|
31213
31225
|
// allow it outside [0,1]
|
|
31214
31226
|
ax.domain = [
|
|
31215
|
-
|
|
31216
|
-
|
|
31227
|
+
vFrac + ypadFrac,
|
|
31228
|
+
vFrac + lenFrac - ypadFrac
|
|
31217
31229
|
];
|
|
31218
31230
|
|
|
31219
31231
|
ax.setScale();
|
|
@@ -31254,15 +31266,15 @@ function drawColorBar(g, opts, gd) {
|
|
|
31254
31266
|
// draw the title so we know how much room it needs
|
|
31255
31267
|
// when we squish the axis. This one only applies to
|
|
31256
31268
|
// top or bottom titles, not right side.
|
|
31257
|
-
var x = gs.l + (
|
|
31269
|
+
var x = gs.l + (optsX + xpadFrac) * gs.w;
|
|
31258
31270
|
var fontSize = ax.title.font.size;
|
|
31259
31271
|
var y;
|
|
31260
31272
|
|
|
31261
31273
|
if(titleSide === 'top') {
|
|
31262
|
-
y = (1 - (
|
|
31274
|
+
y = (1 - (vFrac + lenFrac - ypadFrac)) * gs.h +
|
|
31263
31275
|
gs.t + 3 + fontSize * 0.75;
|
|
31264
31276
|
} else {
|
|
31265
|
-
y = (1 - (
|
|
31277
|
+
y = (1 - (vFrac + ypadFrac)) * gs.h +
|
|
31266
31278
|
gs.t - 3 - fontSize * 0.25;
|
|
31267
31279
|
}
|
|
31268
31280
|
drawTitle(ax._id + 'title', {
|
|
@@ -31301,7 +31313,7 @@ function drawColorBar(g, opts, gd) {
|
|
|
31301
31313
|
// squish the axis top to make room for the title
|
|
31302
31314
|
var titleGroup = g.select('.' + cn.cbtitle);
|
|
31303
31315
|
var titleText = titleGroup.select('text');
|
|
31304
|
-
var titleTrans = [-
|
|
31316
|
+
var titleTrans = [-outlinewidth / 2, outlinewidth / 2];
|
|
31305
31317
|
var mathJaxNode = titleGroup
|
|
31306
31318
|
.select('.h' + ax._id + 'title-math-group')
|
|
31307
31319
|
.node();
|
|
@@ -31373,7 +31385,7 @@ function drawColorBar(g, opts, gd) {
|
|
|
31373
31385
|
// Colorbar cannot currently support opacities so we
|
|
31374
31386
|
// use an opaque fill even when alpha channels present
|
|
31375
31387
|
var fillEl = d3.select(this).attr({
|
|
31376
|
-
x:
|
|
31388
|
+
x: uPx,
|
|
31377
31389
|
width: Math.max(thickPx, 2),
|
|
31378
31390
|
y: d3.min(z),
|
|
31379
31391
|
height: Math.max(d3.max(z) - d3.min(z), 2),
|
|
@@ -31397,7 +31409,7 @@ function drawColorBar(g, opts, gd) {
|
|
|
31397
31409
|
lines.exit().remove();
|
|
31398
31410
|
lines.each(function(d) {
|
|
31399
31411
|
d3.select(this)
|
|
31400
|
-
.attr('d', 'M' +
|
|
31412
|
+
.attr('d', 'M' + uPx + ',' +
|
|
31401
31413
|
(Math.round(ax.c2p(d)) + (line.width / 2) % 1) + 'h' + thickPx)
|
|
31402
31414
|
.call(Drawing.lineGroupStyle, line.width, lineColormap(d), line.dash);
|
|
31403
31415
|
});
|
|
@@ -31405,8 +31417,8 @@ function drawColorBar(g, opts, gd) {
|
|
|
31405
31417
|
// force full redraw of labels and ticks
|
|
31406
31418
|
axLayer.selectAll('g.' + ax._id + 'tick,path').remove();
|
|
31407
31419
|
|
|
31408
|
-
var shift =
|
|
31409
|
-
(
|
|
31420
|
+
var shift = uPx + thickPx +
|
|
31421
|
+
(outlinewidth || 0) / 2 - (opts.ticks === 'outside' ? 1 : 0);
|
|
31410
31422
|
|
|
31411
31423
|
var vals = Axes.calcTicks(ax);
|
|
31412
31424
|
var tickSign = Axes.getTickSigns(ax)[2];
|
|
@@ -31431,9 +31443,9 @@ function drawColorBar(g, opts, gd) {
|
|
|
31431
31443
|
// TODO: why are we redrawing multiple times now with this?
|
|
31432
31444
|
// I guess autoMargin doesn't like being post-promise?
|
|
31433
31445
|
function positionCB() {
|
|
31434
|
-
var
|
|
31446
|
+
var innerThickness = thickPx + outlinewidth / 2;
|
|
31435
31447
|
if(ax.ticklabelposition.indexOf('inside') === -1) {
|
|
31436
|
-
|
|
31448
|
+
innerThickness += Drawing.bBox(axLayer.node()).width;
|
|
31437
31449
|
}
|
|
31438
31450
|
|
|
31439
31451
|
titleEl = titleCont.select('text');
|
|
@@ -31448,66 +31460,65 @@ function drawColorBar(g, opts, gd) {
|
|
|
31448
31460
|
// (except for top/bottom mathjax, above)
|
|
31449
31461
|
// but the weird gs.l is because the titleunshift
|
|
31450
31462
|
// transform gets removed by Drawing.bBox
|
|
31451
|
-
titleWidth = Drawing.bBox(titleCont.node()).right -
|
|
31463
|
+
titleWidth = Drawing.bBox(titleCont.node()).right - uPx - gs.l;
|
|
31452
31464
|
}
|
|
31453
|
-
|
|
31465
|
+
innerThickness = Math.max(innerThickness, titleWidth);
|
|
31454
31466
|
}
|
|
31455
31467
|
|
|
31456
|
-
var
|
|
31457
|
-
var outerheight = yBottomPx - yTopPx;
|
|
31468
|
+
var outerThickness = 2 * xpad + innerThickness + borderwidth + outlinewidth / 2;
|
|
31458
31469
|
|
|
31459
31470
|
g.select('.' + cn.cbbg).attr({
|
|
31460
|
-
x:
|
|
31461
|
-
y:
|
|
31462
|
-
width: Math.max(
|
|
31463
|
-
height: Math.max(
|
|
31471
|
+
x: uPx - xpad - (borderwidth + outlinewidth) / 2,
|
|
31472
|
+
y: vPx - lenPx - yExtraPx,
|
|
31473
|
+
width: Math.max(outerThickness, 2),
|
|
31474
|
+
height: Math.max(lenPx + 2 * yExtraPx, 2)
|
|
31464
31475
|
})
|
|
31465
31476
|
.call(Color.fill, opts.bgcolor)
|
|
31466
31477
|
.call(Color.stroke, opts.bordercolor)
|
|
31467
|
-
.style('stroke-width',
|
|
31478
|
+
.style('stroke-width', borderwidth);
|
|
31468
31479
|
|
|
31469
31480
|
g.selectAll('.' + cn.cboutline).attr({
|
|
31470
|
-
x:
|
|
31471
|
-
y:
|
|
31481
|
+
x: uPx,
|
|
31482
|
+
y: vPx - lenPx + ypad + (titleSide === 'top' ? titleHeight : 0),
|
|
31472
31483
|
width: Math.max(thickPx, 2),
|
|
31473
|
-
height: Math.max(
|
|
31484
|
+
height: Math.max(lenPx - 2 * ypad - titleHeight, 2)
|
|
31474
31485
|
})
|
|
31475
31486
|
.call(Color.stroke, opts.outlinecolor)
|
|
31476
31487
|
.style({
|
|
31477
31488
|
fill: 'none',
|
|
31478
|
-
'stroke-width':
|
|
31489
|
+
'stroke-width': outlinewidth
|
|
31479
31490
|
});
|
|
31480
31491
|
|
|
31481
31492
|
// fix positioning for xanchor!='left'
|
|
31482
|
-
var xoffset = ({center: 0.5, right: 1}[
|
|
31493
|
+
var xoffset = ({center: 0.5, right: 1}[xanchor] || 0) * outerThickness;
|
|
31483
31494
|
g.attr('transform', strTranslate(gs.l - xoffset, gs.t));
|
|
31484
31495
|
|
|
31485
31496
|
// auto margin adjustment
|
|
31486
31497
|
var marginOpts = {};
|
|
31487
|
-
var tFrac = FROM_TL[
|
|
31488
|
-
var bFrac = FROM_BR[
|
|
31489
|
-
if(
|
|
31490
|
-
marginOpts.y =
|
|
31491
|
-
marginOpts.t =
|
|
31492
|
-
marginOpts.b =
|
|
31498
|
+
var tFrac = FROM_TL[yanchor];
|
|
31499
|
+
var bFrac = FROM_BR[yanchor];
|
|
31500
|
+
if(lenmode === 'pixels') {
|
|
31501
|
+
marginOpts.y = optsY;
|
|
31502
|
+
marginOpts.t = lenPx * tFrac;
|
|
31503
|
+
marginOpts.b = lenPx * bFrac;
|
|
31493
31504
|
} else {
|
|
31494
31505
|
marginOpts.t = marginOpts.b = 0;
|
|
31495
|
-
marginOpts.yt =
|
|
31496
|
-
marginOpts.yb =
|
|
31506
|
+
marginOpts.yt = optsY + len * tFrac;
|
|
31507
|
+
marginOpts.yb = optsY - len * bFrac;
|
|
31497
31508
|
}
|
|
31498
31509
|
|
|
31499
|
-
var lFrac = FROM_TL[
|
|
31500
|
-
var rFrac = FROM_BR[
|
|
31501
|
-
if(
|
|
31502
|
-
marginOpts.x =
|
|
31503
|
-
marginOpts.l =
|
|
31504
|
-
marginOpts.r =
|
|
31510
|
+
var lFrac = FROM_TL[xanchor];
|
|
31511
|
+
var rFrac = FROM_BR[xanchor];
|
|
31512
|
+
if(thicknessmode === 'pixels') {
|
|
31513
|
+
marginOpts.x = optsX;
|
|
31514
|
+
marginOpts.l = outerThickness * lFrac;
|
|
31515
|
+
marginOpts.r = outerThickness * rFrac;
|
|
31505
31516
|
} else {
|
|
31506
|
-
var extraThickness =
|
|
31517
|
+
var extraThickness = outerThickness - thickPx;
|
|
31507
31518
|
marginOpts.l = extraThickness * lFrac;
|
|
31508
31519
|
marginOpts.r = extraThickness * rFrac;
|
|
31509
|
-
marginOpts.xl =
|
|
31510
|
-
marginOpts.xr =
|
|
31520
|
+
marginOpts.xl = optsX - thickness * lFrac;
|
|
31521
|
+
marginOpts.xr = optsX + thickness * rFrac;
|
|
31511
31522
|
}
|
|
31512
31523
|
|
|
31513
31524
|
Plots.autoMargin(gd, opts._id, marginOpts);
|
|
@@ -31538,9 +31549,9 @@ function makeEditable(g, opts, gd) {
|
|
|
31538
31549
|
moveFn: function(dx, dy) {
|
|
31539
31550
|
g.attr('transform', t0 + strTranslate(dx, dy));
|
|
31540
31551
|
|
|
31541
|
-
xf = dragElement.align(opts.
|
|
31552
|
+
xf = dragElement.align(opts._uFrac + (dx / gs.w), opts._thickFrac,
|
|
31542
31553
|
0, 1, opts.xanchor);
|
|
31543
|
-
yf = dragElement.align(opts.
|
|
31554
|
+
yf = dragElement.align(opts._vFrac - (dy / gs.h), opts._lenFrac,
|
|
31544
31555
|
0, 1, opts.yanchor);
|
|
31545
31556
|
|
|
31546
31557
|
var csr = dragElement.getCursor(xf, yf, opts.xanchor, opts.yanchor);
|
|
@@ -36242,11 +36253,13 @@ var cartesianScatterPoints = {
|
|
|
36242
36253
|
// The actual rendering is done by private function _hover.
|
|
36243
36254
|
exports.hover = function hover(gd, evt, subplot, noHoverEvent) {
|
|
36244
36255
|
gd = Lib.getGraphDiv(gd);
|
|
36245
|
-
|
|
36256
|
+
// The 'target' property changes when bubbling out of Shadow DOM.
|
|
36257
|
+
// Throttling can delay reading the target, so we save the current value.
|
|
36258
|
+
var eventTarget = evt.target;
|
|
36246
36259
|
Lib.throttle(
|
|
36247
36260
|
gd._fullLayout._uid + constants.HOVERID,
|
|
36248
36261
|
constants.HOVERMINTIME,
|
|
36249
|
-
function() { _hover(gd, evt, subplot, noHoverEvent); }
|
|
36262
|
+
function() { _hover(gd, evt, subplot, noHoverEvent, eventTarget); }
|
|
36250
36263
|
);
|
|
36251
36264
|
};
|
|
36252
36265
|
|
|
@@ -36411,7 +36424,7 @@ exports.loneHover = function loneHover(hoverItems, opts) {
|
|
|
36411
36424
|
};
|
|
36412
36425
|
|
|
36413
36426
|
// The actual implementation is here:
|
|
36414
|
-
function _hover(gd, evt, subplot, noHoverEvent) {
|
|
36427
|
+
function _hover(gd, evt, subplot, noHoverEvent, eventTarget) {
|
|
36415
36428
|
if(!subplot) subplot = 'xy';
|
|
36416
36429
|
|
|
36417
36430
|
// if the user passed in an array of subplots,
|
|
@@ -36530,7 +36543,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
|
|
|
36530
36543
|
// [x|y]px: the pixels (from top left) of the mouse location
|
|
36531
36544
|
// on the currently selected plot area
|
|
36532
36545
|
// add pointerX|Y property for drawing the spikes in spikesnap 'cursor' situation
|
|
36533
|
-
var hasUserCalledHover = !
|
|
36546
|
+
var hasUserCalledHover = !eventTarget;
|
|
36534
36547
|
var xpx, ypx;
|
|
36535
36548
|
|
|
36536
36549
|
if(hasUserCalledHover) {
|
|
@@ -36547,13 +36560,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
|
|
|
36547
36560
|
return;
|
|
36548
36561
|
}
|
|
36549
36562
|
|
|
36550
|
-
|
|
36551
|
-
var target = evt.composedPath && evt.composedPath()[0];
|
|
36552
|
-
if(!target) {
|
|
36553
|
-
// Fallback for browsers not supporting composedPath
|
|
36554
|
-
target = evt.target;
|
|
36555
|
-
}
|
|
36556
|
-
var dbb = target.getBoundingClientRect();
|
|
36563
|
+
var dbb = eventTarget.getBoundingClientRect();
|
|
36557
36564
|
|
|
36558
36565
|
xpx = evt.clientX - dbb.left;
|
|
36559
36566
|
ypx = evt.clientY - dbb.top;
|
|
@@ -37001,15 +37008,15 @@ function _hover(gd, evt, subplot, noHoverEvent) {
|
|
|
37001
37008
|
if(!helpers.isUnifiedHover(hovermode)) {
|
|
37002
37009
|
hoverAvoidOverlaps(hoverLabels, rotateLabels ? 'xa' : 'ya', fullLayout);
|
|
37003
37010
|
alignHoverText(hoverLabels, rotateLabels, fullLayout._invScaleX, fullLayout._invScaleY);
|
|
37004
|
-
} // TODO: tagName hack is needed to appease geo.js's hack of using
|
|
37011
|
+
} // TODO: tagName hack is needed to appease geo.js's hack of using eventTarget=true
|
|
37005
37012
|
// we should improve the "fx" API so other plots can use it without these hack.
|
|
37006
|
-
if(
|
|
37013
|
+
if(eventTarget && eventTarget.tagName) {
|
|
37007
37014
|
var hasClickToShow = Registry.getComponentMethod('annotations', 'hasClickToShow')(gd, newhoverdata);
|
|
37008
|
-
overrideCursor(d3.select(
|
|
37015
|
+
overrideCursor(d3.select(eventTarget), hasClickToShow ? 'pointer' : '');
|
|
37009
37016
|
}
|
|
37010
37017
|
|
|
37011
37018
|
// don't emit events if called manually
|
|
37012
|
-
if(!
|
|
37019
|
+
if(!eventTarget || noHoverEvent || !hoverChanged(gd, evt, oldhoverdata)) return;
|
|
37013
37020
|
|
|
37014
37021
|
if(oldhoverdata) {
|
|
37015
37022
|
gd.emit('plotly_unhover', {
|
|
@@ -102149,7 +102156,7 @@ function getSortFunc(opts, d2c) {
|
|
|
102149
102156
|
'use strict';
|
|
102150
102157
|
|
|
102151
102158
|
// package version injected by `npm run preprocess`
|
|
102152
|
-
exports.version = '2.6.
|
|
102159
|
+
exports.version = '2.6.3';
|
|
102153
102160
|
|
|
102154
102161
|
},{}]},{},[15])(15)
|
|
102155
102162
|
});
|