@atlaspack/core 2.12.1-canary.3597 → 2.12.1-canary.3598
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.
|
@@ -4,6 +4,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = createBundleGraphRequest;
|
|
7
|
+
function _fs() {
|
|
8
|
+
const data = _interopRequireDefault(require("fs"));
|
|
9
|
+
_fs = function () {
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
7
14
|
function _assert() {
|
|
8
15
|
const data = _interopRequireDefault(require("assert"));
|
|
9
16
|
_assert = function () {
|
|
@@ -72,6 +79,7 @@ function _profiler() {
|
|
|
72
79
|
return data;
|
|
73
80
|
}
|
|
74
81
|
var _RequestTracker = require("../RequestTracker");
|
|
82
|
+
var _assetGraphDot = require("./asset-graph-dot");
|
|
75
83
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
76
84
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
77
85
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -109,6 +117,10 @@ function createBundleGraphRequest(input) {
|
|
|
109
117
|
} = await api.runRequest(request, {
|
|
110
118
|
force: options.shouldBuildLazily && requestedAssetIds.size > 0
|
|
111
119
|
});
|
|
120
|
+
let debugAssetGraphDotPath = (0, _assetGraphDot.getDebugAssetGraphDotPath)();
|
|
121
|
+
if (debugAssetGraphDotPath !== null) {
|
|
122
|
+
await _fs().default.promises.writeFile(debugAssetGraphDotPath, (0, _assetGraphDot.assetGraphToDot)(assetGraph, (0, _assetGraphDot.getDebugAssetGraphDotOptions)()), 'utf8');
|
|
123
|
+
}
|
|
112
124
|
|
|
113
125
|
// if (input.rustAtlaspack && process.env.NATIVE_COMPARE === 'true') {
|
|
114
126
|
// let {assetGraph: jsAssetGraph} = await api.runRequest(
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.assetGraphToDot = assetGraphToDot;
|
|
7
|
+
exports.getDebugAssetGraphDotOptions = getDebugAssetGraphDotOptions;
|
|
8
|
+
exports.getDebugAssetGraphDotPath = getDebugAssetGraphDotPath;
|
|
9
|
+
function _path() {
|
|
10
|
+
const data = _interopRequireDefault(require("path"));
|
|
11
|
+
_path = function () {
|
|
12
|
+
return data;
|
|
13
|
+
};
|
|
14
|
+
return data;
|
|
15
|
+
}
|
|
16
|
+
var _AssetGraph = _interopRequireDefault(require("../AssetGraph"));
|
|
17
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
|
+
/** @description Renders AssetGraph into GraphViz Dot format */
|
|
19
|
+
function assetGraphToDot(assetGraph, {
|
|
20
|
+
sort = false,
|
|
21
|
+
style = true
|
|
22
|
+
} = {}) {
|
|
23
|
+
const edges = [];
|
|
24
|
+
const nodeStyles = {};
|
|
25
|
+
assetGraph.traverse(nodeId => {
|
|
26
|
+
let node = assetGraph.getNode(nodeId) ?? null;
|
|
27
|
+
if (!node) return;
|
|
28
|
+
const fromIds = assetGraph.getNodeIdsConnectedTo(nodeId);
|
|
29
|
+
for (const fromId of fromIds) {
|
|
30
|
+
let fromNode = assetGraph.getNode(fromId) ?? null;
|
|
31
|
+
if (!fromNode) throw new Error('No Node');
|
|
32
|
+
const edgeStyle = getEdgeStyle(node);
|
|
33
|
+
const nodeStyle = getNodeStyle(node);
|
|
34
|
+
let entry = `"${getNodeName(fromNode)}" -> "${getNodeName(node)}"`;
|
|
35
|
+
if (edgeStyle) {
|
|
36
|
+
entry += ` [${edgeStyle}]`;
|
|
37
|
+
}
|
|
38
|
+
if (nodeStyle) {
|
|
39
|
+
nodeStyles[getNodeName(node)] = nodeStyle;
|
|
40
|
+
}
|
|
41
|
+
edges.push(entry);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// $FlowFixMe
|
|
46
|
+
const nodeStylesList = Object.entries(nodeStyles);
|
|
47
|
+
if (sort) {
|
|
48
|
+
edges.sort();
|
|
49
|
+
nodeStylesList.sort();
|
|
50
|
+
}
|
|
51
|
+
let digraph = `digraph {\n\tnode [shape=rectangle]\n`;
|
|
52
|
+
if (style) {
|
|
53
|
+
digraph += nodeStylesList.map(([node, style]) => `\t"${node}" [${style}]\n`).join('');
|
|
54
|
+
}
|
|
55
|
+
digraph += edges.map(v => `\t${v}\n`).join('');
|
|
56
|
+
digraph += `}\n`;
|
|
57
|
+
return digraph;
|
|
58
|
+
}
|
|
59
|
+
function getDebugAssetGraphDotPath() {
|
|
60
|
+
let debugAssetGraphDot = process.env.DEBUG_ASSET_GRAPH_DOT;
|
|
61
|
+
if (debugAssetGraphDot === undefined || debugAssetGraphDot === '') {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
if (!_path().default.isAbsolute(debugAssetGraphDot)) {
|
|
65
|
+
debugAssetGraphDot = _path().default.join(process.cwd(), debugAssetGraphDot);
|
|
66
|
+
}
|
|
67
|
+
return debugAssetGraphDot;
|
|
68
|
+
}
|
|
69
|
+
function getDebugAssetGraphDotOptions() {
|
|
70
|
+
const options = {};
|
|
71
|
+
let style = process.env.DEBUG_ASSET_GRAPH_DOT_STYLE;
|
|
72
|
+
if (style !== undefined) {
|
|
73
|
+
options.style = style === 'true';
|
|
74
|
+
}
|
|
75
|
+
let sort = process.env.DEBUG_ASSET_GRAPH_DOT_SORT;
|
|
76
|
+
if (sort !== undefined) {
|
|
77
|
+
options.sort = sort === 'true';
|
|
78
|
+
}
|
|
79
|
+
return options;
|
|
80
|
+
}
|
|
81
|
+
function fromCwd(input) {
|
|
82
|
+
return _path().default.relative(process.cwd(), input);
|
|
83
|
+
}
|
|
84
|
+
function getNodeName(node) {
|
|
85
|
+
if (node.type === 'asset_group') {
|
|
86
|
+
// $FlowFixMe
|
|
87
|
+
return [`asset_group`, node.id, fromCwd(node.value.filePath)].join('\\n');
|
|
88
|
+
} else if (node.type === 'asset') {
|
|
89
|
+
// $FlowFixMe
|
|
90
|
+
return [`asset`, node.id, fromCwd(node.value.filePath)].join('\\n');
|
|
91
|
+
} else if (node.type === 'dependency') {
|
|
92
|
+
return [`dependency`, node.id, node.value.specifier].join('\\n');
|
|
93
|
+
} else if (node.type === 'entry_specifier') {
|
|
94
|
+
// $FlowFixMe
|
|
95
|
+
return [`entry_specifier`, node.value].join('\\n');
|
|
96
|
+
} else if (node.type === 'entry_file') {
|
|
97
|
+
// $FlowFixMe
|
|
98
|
+
return [`entry_file`, fromCwd(node.value.filePath)].join('\\n');
|
|
99
|
+
}
|
|
100
|
+
return 'ROOT';
|
|
101
|
+
}
|
|
102
|
+
function getEdgeStyle(node) {
|
|
103
|
+
if (node.type === 'asset_group') {
|
|
104
|
+
return ``;
|
|
105
|
+
} else if (node.type === 'asset') {
|
|
106
|
+
return ``;
|
|
107
|
+
} else if (node.type === 'dependency') {
|
|
108
|
+
if (node.value.priority === 2) {
|
|
109
|
+
return `style="dashed"`;
|
|
110
|
+
}
|
|
111
|
+
} else if (node.type === 'entry_specifier') {
|
|
112
|
+
return ``;
|
|
113
|
+
} else if (node.type === 'entry_file') {
|
|
114
|
+
return ``;
|
|
115
|
+
}
|
|
116
|
+
return '';
|
|
117
|
+
}
|
|
118
|
+
function getNodeStyle(node) {
|
|
119
|
+
if (node.type === 'asset_group') {
|
|
120
|
+
return `fillcolor="#E8F5E9", style="filled"`;
|
|
121
|
+
} else if (node.type === 'asset') {
|
|
122
|
+
return `fillcolor="#DCEDC8", style="filled"`;
|
|
123
|
+
} else if (node.type === 'dependency') {
|
|
124
|
+
return `fillcolor="#BBDEFB", style="filled"`;
|
|
125
|
+
} else if (node.type === 'entry_specifier') {
|
|
126
|
+
return `fillcolor="#FFF9C4", style="filled"`;
|
|
127
|
+
} else if (node.type === 'entry_file') {
|
|
128
|
+
return `fillcolor="#FFE0B2", style="filled"`;
|
|
129
|
+
}
|
|
130
|
+
return '';
|
|
131
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/core",
|
|
3
|
-
"version": "2.12.1-canary.
|
|
3
|
+
"version": "2.12.1-canary.3598+43565eabc",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -20,21 +20,21 @@
|
|
|
20
20
|
"check-ts": "tsc --noEmit index.d.ts"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@atlaspack/build-cache": "2.12.1-canary.
|
|
24
|
-
"@atlaspack/cache": "2.12.1-canary.
|
|
25
|
-
"@atlaspack/diagnostic": "2.12.1-canary.
|
|
26
|
-
"@atlaspack/events": "2.12.1-canary.
|
|
27
|
-
"@atlaspack/feature-flags": "2.12.1-canary.
|
|
28
|
-
"@atlaspack/fs": "2.12.1-canary.
|
|
29
|
-
"@atlaspack/graph": "3.2.1-canary.
|
|
30
|
-
"@atlaspack/logger": "2.12.1-canary.
|
|
31
|
-
"@atlaspack/package-manager": "2.12.1-canary.
|
|
32
|
-
"@atlaspack/plugin": "2.12.1-canary.
|
|
33
|
-
"@atlaspack/profiler": "2.12.1-canary.
|
|
34
|
-
"@atlaspack/rust": "2.12.1-canary.
|
|
35
|
-
"@atlaspack/types": "2.12.1-canary.
|
|
36
|
-
"@atlaspack/utils": "2.12.1-canary.
|
|
37
|
-
"@atlaspack/workers": "2.12.1-canary.
|
|
23
|
+
"@atlaspack/build-cache": "2.12.1-canary.3598+43565eabc",
|
|
24
|
+
"@atlaspack/cache": "2.12.1-canary.3598+43565eabc",
|
|
25
|
+
"@atlaspack/diagnostic": "2.12.1-canary.3598+43565eabc",
|
|
26
|
+
"@atlaspack/events": "2.12.1-canary.3598+43565eabc",
|
|
27
|
+
"@atlaspack/feature-flags": "2.12.1-canary.3598+43565eabc",
|
|
28
|
+
"@atlaspack/fs": "2.12.1-canary.3598+43565eabc",
|
|
29
|
+
"@atlaspack/graph": "3.2.1-canary.3598+43565eabc",
|
|
30
|
+
"@atlaspack/logger": "2.12.1-canary.3598+43565eabc",
|
|
31
|
+
"@atlaspack/package-manager": "2.12.1-canary.3598+43565eabc",
|
|
32
|
+
"@atlaspack/plugin": "2.12.1-canary.3598+43565eabc",
|
|
33
|
+
"@atlaspack/profiler": "2.12.1-canary.3598+43565eabc",
|
|
34
|
+
"@atlaspack/rust": "2.12.1-canary.3598+43565eabc",
|
|
35
|
+
"@atlaspack/types": "2.12.1-canary.3598+43565eabc",
|
|
36
|
+
"@atlaspack/utils": "2.12.1-canary.3598+43565eabc",
|
|
37
|
+
"@atlaspack/workers": "2.12.1-canary.3598+43565eabc",
|
|
38
38
|
"@mischnic/json-sourcemap": "^0.1.0",
|
|
39
39
|
"@parcel/source-map": "^2.1.1",
|
|
40
40
|
"base-x": "^3.0.8",
|
|
@@ -66,5 +66,5 @@
|
|
|
66
66
|
"browser": {
|
|
67
67
|
"./src/serializerCore.js": "./src/serializerCore.browser.js"
|
|
68
68
|
},
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "43565eabcda613c67cbf579d38b1093a7c629955"
|
|
70
70
|
}
|
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
} from '../types';
|
|
16
16
|
import type {ConfigAndCachePath} from './AtlaspackConfigRequest';
|
|
17
17
|
|
|
18
|
+
import fs from 'fs';
|
|
18
19
|
import invariant from 'assert';
|
|
19
20
|
import assert from 'assert';
|
|
20
21
|
import nullthrows from 'nullthrows';
|
|
@@ -57,6 +58,11 @@ import createAssetGraphRequestJS from './AssetGraphRequest';
|
|
|
57
58
|
import {createAssetGraphRequestRust} from './AssetGraphRequestRust';
|
|
58
59
|
import {tracer, PluginTracer} from '@atlaspack/profiler';
|
|
59
60
|
import {requestTypes} from '../RequestTracker';
|
|
61
|
+
import {
|
|
62
|
+
assetGraphToDot,
|
|
63
|
+
getDebugAssetGraphDotPath,
|
|
64
|
+
getDebugAssetGraphDotOptions,
|
|
65
|
+
} from './asset-graph-dot';
|
|
60
66
|
|
|
61
67
|
type BundleGraphRequestInput = {|
|
|
62
68
|
requestedAssetIds: Set<string>,
|
|
@@ -119,6 +125,15 @@ export default function createBundleGraphRequest(
|
|
|
119
125
|
},
|
|
120
126
|
);
|
|
121
127
|
|
|
128
|
+
let debugAssetGraphDotPath = getDebugAssetGraphDotPath();
|
|
129
|
+
if (debugAssetGraphDotPath !== null) {
|
|
130
|
+
await fs.promises.writeFile(
|
|
131
|
+
debugAssetGraphDotPath,
|
|
132
|
+
assetGraphToDot(assetGraph, getDebugAssetGraphDotOptions()),
|
|
133
|
+
'utf8',
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
122
137
|
// if (input.rustAtlaspack && process.env.NATIVE_COMPARE === 'true') {
|
|
123
138
|
// let {assetGraph: jsAssetGraph} = await api.runRequest(
|
|
124
139
|
// createAssetGraphRequestJS({
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
|
+
import type {AssetGraphNode} from '../types';
|
|
5
|
+
import AssetGraph from '../AssetGraph';
|
|
6
|
+
|
|
7
|
+
export type AssetGraphToDotOptions = {
|
|
8
|
+
style?: boolean,
|
|
9
|
+
sort?: boolean,
|
|
10
|
+
...
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** @description Renders AssetGraph into GraphViz Dot format */
|
|
14
|
+
export function assetGraphToDot(
|
|
15
|
+
assetGraph: AssetGraph,
|
|
16
|
+
{sort = false, style = true}: AssetGraphToDotOptions = {},
|
|
17
|
+
): string {
|
|
18
|
+
const edges = [];
|
|
19
|
+
const nodeStyles: {[key: string]: string} = {};
|
|
20
|
+
|
|
21
|
+
assetGraph.traverse((nodeId) => {
|
|
22
|
+
let node: AssetGraphNode | null = assetGraph.getNode(nodeId) ?? null;
|
|
23
|
+
if (!node) return;
|
|
24
|
+
|
|
25
|
+
const fromIds = assetGraph.getNodeIdsConnectedTo(nodeId);
|
|
26
|
+
|
|
27
|
+
for (const fromId of fromIds) {
|
|
28
|
+
let fromNode: AssetGraphNode | null = assetGraph.getNode(fromId) ?? null;
|
|
29
|
+
if (!fromNode) throw new Error('No Node');
|
|
30
|
+
const edgeStyle = getEdgeStyle(node);
|
|
31
|
+
const nodeStyle = getNodeStyle(node);
|
|
32
|
+
|
|
33
|
+
let entry = `"${getNodeName(fromNode)}" -> "${getNodeName(node)}"`;
|
|
34
|
+
if (edgeStyle) {
|
|
35
|
+
entry += ` [${edgeStyle}]`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (nodeStyle) {
|
|
39
|
+
nodeStyles[getNodeName(node)] = nodeStyle;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
edges.push(entry);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// $FlowFixMe
|
|
47
|
+
const nodeStylesList: Array<[string, string]> = Object.entries(nodeStyles);
|
|
48
|
+
if (sort) {
|
|
49
|
+
edges.sort();
|
|
50
|
+
nodeStylesList.sort();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let digraph = `digraph {\n\tnode [shape=rectangle]\n`;
|
|
54
|
+
if (style) {
|
|
55
|
+
digraph += nodeStylesList
|
|
56
|
+
.map(([node, style]) => `\t"${node}" [${style}]\n`)
|
|
57
|
+
.join('');
|
|
58
|
+
}
|
|
59
|
+
digraph += edges.map((v) => `\t${v}\n`).join('');
|
|
60
|
+
digraph += `}\n`;
|
|
61
|
+
return digraph;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function getDebugAssetGraphDotPath(): string | null {
|
|
65
|
+
let debugAssetGraphDot = process.env.DEBUG_ASSET_GRAPH_DOT;
|
|
66
|
+
if (debugAssetGraphDot === undefined || debugAssetGraphDot === '') {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
if (!path.isAbsolute(debugAssetGraphDot)) {
|
|
70
|
+
debugAssetGraphDot = path.join(process.cwd(), debugAssetGraphDot);
|
|
71
|
+
}
|
|
72
|
+
return debugAssetGraphDot;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function getDebugAssetGraphDotOptions(): AssetGraphToDotOptions {
|
|
76
|
+
const options: AssetGraphToDotOptions = {};
|
|
77
|
+
|
|
78
|
+
let style = process.env.DEBUG_ASSET_GRAPH_DOT_STYLE;
|
|
79
|
+
if (style !== undefined) {
|
|
80
|
+
options.style = style === 'true';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let sort = process.env.DEBUG_ASSET_GRAPH_DOT_SORT;
|
|
84
|
+
if (sort !== undefined) {
|
|
85
|
+
options.sort = sort === 'true';
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return options;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function fromCwd(input: string): string {
|
|
92
|
+
return path.relative(process.cwd(), input);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function getNodeName(node: AssetGraphNode): string {
|
|
96
|
+
if (node.type === 'asset_group') {
|
|
97
|
+
// $FlowFixMe
|
|
98
|
+
return [`asset_group`, node.id, fromCwd(node.value.filePath)].join('\\n');
|
|
99
|
+
} else if (node.type === 'asset') {
|
|
100
|
+
// $FlowFixMe
|
|
101
|
+
return [`asset`, node.id, fromCwd(node.value.filePath)].join('\\n');
|
|
102
|
+
} else if (node.type === 'dependency') {
|
|
103
|
+
return [`dependency`, node.id, node.value.specifier].join('\\n');
|
|
104
|
+
} else if (node.type === 'entry_specifier') {
|
|
105
|
+
// $FlowFixMe
|
|
106
|
+
return [`entry_specifier`, node.value].join('\\n');
|
|
107
|
+
} else if (node.type === 'entry_file') {
|
|
108
|
+
// $FlowFixMe
|
|
109
|
+
return [`entry_file`, fromCwd(node.value.filePath)].join('\\n');
|
|
110
|
+
}
|
|
111
|
+
return 'ROOT';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function getEdgeStyle(node: AssetGraphNode): string {
|
|
115
|
+
if (node.type === 'asset_group') {
|
|
116
|
+
return ``;
|
|
117
|
+
} else if (node.type === 'asset') {
|
|
118
|
+
return ``;
|
|
119
|
+
} else if (node.type === 'dependency') {
|
|
120
|
+
if (node.value.priority === 2) {
|
|
121
|
+
return `style="dashed"`;
|
|
122
|
+
}
|
|
123
|
+
} else if (node.type === 'entry_specifier') {
|
|
124
|
+
return ``;
|
|
125
|
+
} else if (node.type === 'entry_file') {
|
|
126
|
+
return ``;
|
|
127
|
+
}
|
|
128
|
+
return '';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function getNodeStyle(node: AssetGraphNode): string {
|
|
132
|
+
if (node.type === 'asset_group') {
|
|
133
|
+
return `fillcolor="#E8F5E9", style="filled"`;
|
|
134
|
+
} else if (node.type === 'asset') {
|
|
135
|
+
return `fillcolor="#DCEDC8", style="filled"`;
|
|
136
|
+
} else if (node.type === 'dependency') {
|
|
137
|
+
return `fillcolor="#BBDEFB", style="filled"`;
|
|
138
|
+
} else if (node.type === 'entry_specifier') {
|
|
139
|
+
return `fillcolor="#FFF9C4", style="filled"`;
|
|
140
|
+
} else if (node.type === 'entry_file') {
|
|
141
|
+
return `fillcolor="#FFE0B2", style="filled"`;
|
|
142
|
+
}
|
|
143
|
+
return '';
|
|
144
|
+
}
|