UNPKG

16.2 kBJavaScriptView Raw
1"use strict";
2var __extends = (this && this.__extends) || (function () {
3 var extendStatics = Object.setPrototypeOf ||
4 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6 return function (d, b) {
7 extendStatics(d, b);
8 function __() { this.constructor = d; }
9 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
10 };
11})();
12var __assign = (this && this.__assign) || Object.assign || function(t) {
13 for (var s, i = 1, n = arguments.length; i < n; i++) {
14 s = arguments[i];
15 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
16 t[p] = s[p];
17 }
18 return t;
19};
20Object.defineProperty(exports, "__esModule", { value: true });
21//import { BridgeDb, XrefsAnnotationPanel } from "bridgedb";
22var React = require("react");
23// TODO look at how to properly import this so it works
24// for both es5, esnext, tree-shaking, etc.
25//import { Kaavio } from "kaavio";
26var Kaavio_1 = require("kaavio/esnext/Kaavio");
27// The edge drawing definitions are in Kaavio because they can be generically used.
28// But the icons and markers are specific to Pvjs (less likely to useful to other applications).
29var theme = require("./themes/plain/theme");
30var ContainerCustomStyle = require("./themes/styles/Container.css");
31var DiagramCustomStylePlain = require("./themes/styles/Diagram.plain.css");
32var DiagramCustomStyleDark = require("./themes/styles/Diagram.dark.css");
33var diagramStyles = {
34 plain: DiagramCustomStylePlain,
35 dark: DiagramCustomStyleDark
36};
37// TODO use TS types updated for version 16. But I also have some changes
38// I made for SVG attributes that need to get merged.
39var Fragment = React["Fragment"];
40// TODO move this into utils
41// Create a string of citation numbers for display,
42// delimited by commas, and
43// replacing any consecutive series of numbers with the
44// first and last joined by a hyphen.
45function createPublicationXrefString(displayNumbers) {
46 var publicationXrefString;
47 if (displayNumbers.length === 1) {
48 publicationXrefString = displayNumbers[0];
49 }
50 else {
51 displayNumbers.sort(function (a, b) {
52 return a - b;
53 });
54 var i = 0;
55 publicationXrefString = displayNumbers[i].toString();
56 if (displayNumbers.length > 2) {
57 do {
58 i += 1;
59 if (displayNumbers[i - 1] + 1 !== displayNumbers[i] ||
60 displayNumbers[i] + 1 !== displayNumbers[i + 1]) {
61 if (i !== 1) {
62 if (displayNumbers[i - 2] + 2 === displayNumbers[i]) {
63 publicationXrefString += "-" + displayNumbers[i].toString();
64 }
65 else {
66 publicationXrefString += ", " + displayNumbers[i].toString();
67 }
68 }
69 else {
70 publicationXrefString += ", " + displayNumbers[i].toString();
71 }
72 }
73 } while (i < displayNumbers.length - 2);
74 }
75 i += 1;
76 if (displayNumbers[i - 2] + 2 === displayNumbers[i]) {
77 publicationXrefString += "-" + displayNumbers[i].toString();
78 }
79 else {
80 publicationXrefString += ", " + displayNumbers[i].toString();
81 }
82 }
83 return publicationXrefString;
84}
85var Pvjs = /** @class */ (function (_super) {
86 __extends(Pvjs, _super);
87 function Pvjs(props) {
88 var _this = _super.call(this, props) || this;
89 _this.handleEntityClick = function (entity) {
90 var _a = _this.props, onEntityClick = _a.onEntityClick, _b = _a.detailPanelEnabled, detailPanelEnabled = _b === void 0 ? true : _b;
91 if (onEntityClick)
92 onEntityClick(entity);
93 if (entity.type.indexOf("DataNode") > -1 &&
94 entity.xrefIdentifier &&
95 entity.xrefDataSource) {
96 _this.setState({ selected: entity, detailPanelOpen: detailPanelEnabled });
97 }
98 };
99 _this.state = {
100 diagramStyle: props.diagramStyle,
101 hidden: props.hidden,
102 highlighted: props.highlighted,
103 pvjson: props.pvjson,
104 detailPanelOpen: false,
105 selected: null
106 };
107 return _this;
108 }
109 Pvjs.prototype.closeActive = function () {
110 this.setState({ selected: null, detailPanelOpen: false });
111 };
112 Pvjs.prototype.componentWillMount = function () { };
113 Pvjs.prototype.shouldComponentUpdate = function (nextProps, nextState) {
114 var prevProps = this.props;
115 return (nextProps.wpId == prevProps.wpId &&
116 nextProps.version !== prevProps.version);
117 };
118 Pvjs.prototype.componentWillReceiveProps = function (nextProps) {
119 var prevProps = this.props;
120 if (nextProps.wpId !== prevProps.wpId ||
121 nextProps.version !== prevProps.version) {
122 // Reset the state
123 this.setState({
124 pvjson: null,
125 filter: null,
126 detailPanelOpen: false,
127 selected: null
128 });
129 }
130 };
131 Pvjs.prototype.componentWillUnmount = function () {
132 // TODO cancel any pending network requests, possibly something like this:
133 // this.pathwayRequest.dispose();
134 };
135 Pvjs.prototype.onKaavioReady = function () {
136 var onReady = this.props.onReady;
137 if (onReady) {
138 var pvjson = this.state.pvjson;
139 onReady(pvjson.entitiesById);
140 }
141 };
142 Pvjs.prototype.handleCloseDetailsPanel = function () {
143 this.setState({ detailPanelOpen: false });
144 };
145 Pvjs.prototype.renderDetailsPanel = function () {
146 var _a = this.state, pvjson = _a.pvjson, selected = _a.selected, detailPanelOpen = _a.detailPanelOpen;
147 if (!detailPanelOpen)
148 return null;
149 if (window.hasOwnProperty("XrefPanel")) {
150 if (!!selected.xrefDataSource && !!selected.xrefIdentifier) {
151 window["XrefPanel"]["show"](this.detailsPanelRef, selected.xrefIdentifier, selected.xrefDataSource, pvjson.pathway.organism, {
152 "0": selected.textContent
153 });
154 }
155 }
156 /*
157 return (
158 <XrefsAnnotationPanel
159 key="details-panel"
160 bridgeDb={new BridgeDb()}
161 organism={pvjson.organism}
162 entityType={!!selected && selected.wpType}
163 displayName={!!selected && selected.textContent}
164 dataSource={selected && selected.xrefDataSource}
165 identifier={!!selected && selected.xrefIdentifier}
166 handleClose={_ => this.handleCloseDetailsPanel()}
167 />
168 );
169 //*/
170 };
171 Pvjs.prototype.renderKaavio = function () {
172 var pvjson = this.state.pvjson;
173 var _a = this.props, wpId = _a.wpId, showPanZoomControls = _a.showPanZoomControls, highlightedEntities = _a.highlightedEntities, hiddenEntities = _a.hiddenEntities, zoomedEntities = _a.zoomedEntities, pannedEntities = _a.pannedEntities, panCoordinates = _a.panCoordinates, zoomLevel = _a.zoomLevel, onPanZoomChange = _a.onPanZoomChange, panZoomLocked = _a.panZoomLocked;
174 var diagramStyle = this.props.diagramStyle || "plain";
175 return (React.createElement(Kaavio_1.Kaavio, { theme: __assign({ containerStyle: ContainerCustomStyle, diagramStyle: diagramStyles[diagramStyle] }, theme), pathway: pvjson.pathway, entitiesById: pvjson.entitiesById, onReady: function () {
176 // Do something
177 }, onEntityClick: this.handleEntityClick }));
178 /*
179 return (
180 <Kaavio
181 ref={kaavio => (this.kaavioRef = kaavio)}
182 onEntityClick={this.handleEntityClick}
183 entities={pvjson.entities}
184 name={pvjson.name}
185 width={pvjson.width}
186 height={pvjson.height}
187 backgroundColor={pvjson.backgroundColor}
188 customStyle={customStyle}
189 edgeDrawers={EdgeDrawers}
190 icons={icons}
191 markerDrawers={markerDrawers}
192 filters={filters}
193 highlightedEntities={highlightedEntities}
194 hiddenEntities={hiddenEntities}
195 pannedEntities={pannedEntities}
196 zoomedEntities={zoomedEntities}
197 panCoordinates={panCoordinates}
198 zoomLevel={zoomLevel}
199 onPanZoomChange={onPanZoomChange}
200 panZoomLocked={panZoomLocked}
201 onReady={kaavio => this.onKaavioReady()}
202 showPanZoomControls={showPanZoomControls}
203 />
204 );
205 //*/
206 };
207 Pvjs.prototype.render = function () {
208 var _this = this;
209 var state = this.state;
210 return (React.createElement(Fragment, null,
211 React.createElement("div", { ref: function (div) {
212 _this.detailsPanelRef = div;
213 } }),
214 this.renderDetailsPanel(),
215 this.renderKaavio()));
216 };
217 return Pvjs;
218}(React.Component));
219exports.Pvjs = Pvjs;
220//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHZqcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9QdmpzLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLDREQUE0RDtBQUU1RCw2QkFBK0I7QUFHL0IsdURBQXVEO0FBQ3ZELDJDQUEyQztBQUMzQyxrQ0FBa0M7QUFDbEMsK0NBQThDO0FBRTlDLG1GQUFtRjtBQUNuRixnR0FBZ0c7QUFDaEcsNENBQThDO0FBQzlDLElBQU0sb0JBQW9CLEdBQUcsT0FBTyxDQUFDLCtCQUErQixDQUFDLENBQUM7QUFDdEUsSUFBTSx1QkFBdUIsR0FBRyxPQUFPLENBQUMsbUNBQW1DLENBQUMsQ0FBQztBQUM3RSxJQUFNLHNCQUFzQixHQUFHLE9BQU8sQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO0FBQzNFLElBQU0sYUFBYSxHQUFHO0lBQ3BCLEtBQUssRUFBRSx1QkFBdUI7SUFDOUIsSUFBSSxFQUFFLHNCQUFzQjtDQUM3QixDQUFDO0FBRUYseUVBQXlFO0FBQ3pFLHFEQUFxRDtBQUNyRCxJQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7QUFFbkMsNEJBQTRCO0FBQzVCLG1EQUFtRDtBQUNuRCwyQkFBMkI7QUFDM0IsdURBQXVEO0FBQ3ZELHFDQUFxQztBQUNyQyxxQ0FBcUMsY0FBYztJQUNqRCxJQUFJLHFCQUFxQixDQUFDO0lBQzFCLEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoQyxxQkFBcUIsR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUFDLElBQUksQ0FBQyxDQUFDO1FBQ04sY0FBYyxDQUFDLElBQUksQ0FBQyxVQUFTLENBQUMsRUFBRSxDQUFDO1lBQy9CLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2YsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDVixxQkFBcUIsR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7UUFFckQsRUFBRSxDQUFDLENBQUMsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlCLEdBQUcsQ0FBQztnQkFDRixDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUVQLEVBQUUsQ0FBQyxDQUNELGNBQWMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLGNBQWMsQ0FBQyxDQUFDLENBQUM7b0JBQy9DLGNBQWMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssY0FBYyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQ2hELENBQUMsQ0FBQyxDQUFDO29CQUNELEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUNaLEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7NEJBQ3BELHFCQUFxQixJQUFJLEdBQUcsR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7d0JBQzlELENBQUM7d0JBQUMsSUFBSSxDQUFDLENBQUM7NEJBQ04scUJBQXFCLElBQUksSUFBSSxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQzt3QkFDL0QsQ0FBQztvQkFDSCxDQUFDO29CQUFDLElBQUksQ0FBQyxDQUFDO3dCQUNOLHFCQUFxQixJQUFJLElBQUksR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7b0JBQy9ELENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUMsUUFBUSxDQUFDLEdBQUcsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7UUFDMUMsQ0FBQztRQUVELENBQUMsSUFBSSxDQUFDLENBQUM7UUFFUCxFQUFFLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsS0FBSyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3BELHFCQUFxQixJQUFJLEdBQUcsR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDOUQsQ0FBQztRQUFDLElBQUksQ0FBQyxDQUFDO1lBQ04scUJBQXFCLElBQUksSUFBSSxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMvRCxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQztBQUMvQixDQUFDO0FBRUQ7SUFBMEIsd0JBQXlCO0lBSWpELGNBQVksS0FBSztRQUFqQixZQUNFLGtCQUFNLEtBQUssQ0FBQyxTQVNiO1FBTUQsdUJBQWlCLEdBQUcsVUFBQSxNQUFNO1lBQ2xCLElBQUEsZ0JBQXlELEVBQXZELGdDQUFhLEVBQUUsMEJBQXlCLEVBQXpCLDhDQUF5QixDQUFnQjtZQUNoRSxFQUFFLENBQUMsQ0FBQyxhQUFhLENBQUM7Z0JBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRXpDLEVBQUUsQ0FBQyxDQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDcEMsTUFBTSxDQUFDLGNBQWM7Z0JBQ3JCLE1BQU0sQ0FBQyxjQUNULENBQUMsQ0FBQyxDQUFDO2dCQUNELEtBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLGVBQWUsRUFBRSxrQkFBa0IsRUFBRSxDQUFDLENBQUM7WUFDM0UsQ0FBQztRQUNILENBQUMsQ0FBQztRQXpCQSxLQUFJLENBQUMsS0FBSyxHQUFHO1lBQ1gsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZO1lBQ2hDLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtZQUNwQixXQUFXLEVBQUUsS0FBSyxDQUFDLFdBQVc7WUFDOUIsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNO1lBQ3BCLGVBQWUsRUFBRSxLQUFLO1lBQ3RCLFFBQVEsRUFBRSxJQUFJO1NBQ2YsQ0FBQzs7SUFDSixDQUFDO0lBRUQsMEJBQVcsR0FBWDtRQUNFLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFlRCxpQ0FBa0IsR0FBbEIsY0FBc0IsQ0FBQztJQUV2QixvQ0FBcUIsR0FBckIsVUFBc0IsU0FBUyxFQUFFLFNBQVM7UUFDeEMsSUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUM3QixNQUFNLENBQUMsQ0FDTCxTQUFTLENBQUMsSUFBSSxJQUFJLFNBQVMsQ0FBQyxJQUFJO1lBQ2hDLFNBQVMsQ0FBQyxPQUFPLEtBQUssU0FBUyxDQUFDLE9BQU8sQ0FDeEMsQ0FBQztJQUNKLENBQUM7SUFFRCx3Q0FBeUIsR0FBekIsVUFBMEIsU0FBUztRQUNqQyxJQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQzdCLEVBQUUsQ0FBQyxDQUNELFNBQVMsQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDLElBQUk7WUFDakMsU0FBUyxDQUFDLE9BQU8sS0FBSyxTQUFTLENBQUMsT0FDbEMsQ0FBQyxDQUFDLENBQUM7WUFDRCxrQkFBa0I7WUFDbEIsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDWixNQUFNLEVBQUUsSUFBSTtnQkFDWixNQUFNLEVBQUUsSUFBSTtnQkFDWixlQUFlLEVBQUUsS0FBSztnQkFDdEIsUUFBUSxFQUFFLElBQUk7YUFDZixDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztJQUVELG1DQUFvQixHQUFwQjtRQUNFLDBFQUEwRTtRQUMxRSxpQ0FBaUM7SUFDbkMsQ0FBQztJQUVELDRCQUFhLEdBQWI7UUFDVSxJQUFBLDRCQUFPLENBQWdCO1FBQy9CLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDSixJQUFBLDBCQUFNLENBQWdCO1lBQzlCLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDL0IsQ0FBQztJQUNILENBQUM7SUFFRCxzQ0FBdUIsR0FBdkI7UUFDRSxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsZUFBZSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVELGlDQUFrQixHQUFsQjtRQUNRLElBQUEsZUFBa0QsRUFBaEQsa0JBQU0sRUFBRSxzQkFBUSxFQUFFLG9DQUFlLENBQWdCO1FBQ3pELEVBQUUsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDO1lBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztRQUVsQyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN2QyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLGNBQWMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNELE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FDekIsSUFBSSxDQUFDLGVBQWUsRUFDcEIsUUFBUSxDQUFDLGNBQWMsRUFDdkIsUUFBUSxDQUFDLGNBQWMsRUFDdkIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQ3ZCO29CQUNFLEdBQUcsRUFBRSxRQUFRLENBQUMsV0FBVztpQkFDMUIsQ0FDRixDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFFRDs7Ozs7Ozs7Ozs7OztZQWFDO0lBQ0gsQ0FBQztJQUVELDJCQUFZLEdBQVo7UUFDVSxJQUFBLDBCQUFNLENBQWdCO1FBQ3hCLElBQUEsZUFXUSxFQVZaLGNBQUksRUFDSiw0Q0FBbUIsRUFDbkIsNENBQW1CLEVBQ25CLGtDQUFjLEVBQ2Qsa0NBQWMsRUFDZCxrQ0FBYyxFQUNkLGtDQUFjLEVBQ2Qsd0JBQVMsRUFDVCxvQ0FBZSxFQUNmLGdDQUFhLENBQ0E7UUFDZixJQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksSUFBSSxPQUFPLENBQUM7UUFFeEQsTUFBTSxDQUFDLENBQ0wsb0JBQUMsZUFBTSxJQUNMLEtBQUssYUFDSCxjQUFjLEVBQUUsb0JBQW9CLEVBQ3BDLFlBQVksRUFBRSxhQUFhLENBQUMsWUFBWSxDQUFDLElBQ3RDLEtBQUssR0FFVixPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sRUFDdkIsWUFBWSxFQUFFLE1BQU0sQ0FBQyxZQUFZLEVBQ2pDLE9BQU8sRUFBRTtnQkFDUCxlQUFlO1lBQ2pCLENBQUMsRUFDRCxhQUFhLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixHQUNyQyxDQUNILENBQUM7UUFFRjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O1lBMkJJO0lBQ04sQ0FBQztJQUVELHFCQUFNLEdBQU47UUFBQSxpQkFhQztRQVpTLElBQUEsa0JBQUssQ0FBVTtRQUN2QixNQUFNLENBQUMsQ0FDTCxvQkFBQyxRQUFRO1lBQ1AsNkJBQ0UsR0FBRyxFQUFFLFVBQUEsR0FBRztvQkFDTixLQUFJLENBQUMsZUFBZSxHQUFHLEdBQUcsQ0FBQztnQkFDN0IsQ0FBQyxHQUNEO1lBQ0QsSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQ3pCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FDWCxDQUNaLENBQUM7SUFDSixDQUFDO0lBQ0gsV0FBQztBQUFELENBQUMsQUExTEQsQ0FBMEIsS0FBSyxDQUFDLFNBQVMsR0EwTHhDO0FBMUxZLG9CQUFJIn0=
\No newline at end of file