1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | require("source-map-support/register");
|
4 | // TODO should I get rid of the lib above for production browser build?
|
5 | var lodash_1 = require("lodash");
|
6 | var fp_1 = require("lodash/fp");
|
7 | var hl = require("highland");
|
8 | var VError = require("verror");
|
9 | var iassign = require("immutable-assign");
|
10 | iassign.setOption({
|
11 | // Deep freeze both input and output. Used in development to make sure they don't change.
|
12 | // TODO watch issue and re-enable when addressed: https://github.com/engineforce/ImassignM/issues/11
|
13 | //freeze: true,
|
14 | ignoreIfNoChange: true
|
15 | });
|
16 | var gpml_utilities_1 = require("./gpml-utilities");
|
17 | var GraphIdManager_1 = require("./GraphIdManager");
|
18 | var GPML_ELEMENT_NAME_TO_KAAVIO_TYPE = {
|
19 | Anchor: "Burr",
|
20 | BiopaxRef: "Citation",
|
21 | DataNode: "SingleFreeNode",
|
22 | GraphicalLine: "Edge",
|
23 | Group: "Group",
|
24 | Interaction: "Edge",
|
25 | Label: "SingleFreeNode",
|
26 | //openControlledVocabulary: "Skip",
|
27 | //PublicationXref: "Skip",
|
28 | Shape: "SingleFreeNode",
|
29 | State: "Burr"
|
30 | };
|
31 | var VALUES_TO_SKIP = ["", null, undefined];
|
32 | // TODO update lodash/fp TS defs to use "x is ..."
|
33 | function isStringTS(x) {
|
34 | return fp_1.isString(x);
|
35 | }
|
36 | function isArrayTS(x) {
|
37 | return fp_1.isArray(x);
|
38 | }
|
39 | // NOTE: isPlainObject does not return true for an instance of a class
|
40 | function isRecord(x) {
|
41 | return !fp_1.isArray(x) && fp_1.isObject(x);
|
42 | }
|
43 | var Processor = /** @class */ (function () {
|
44 | function Processor(KeyMappings, KeyValueConverters, ValueMappings, ValueConverters) {
|
45 | var _this = this;
|
46 | this.output = {
|
47 | pathway: {
|
48 | // NOTE: GPML does not contain a way to express background color.
|
49 | // It's always just white.
|
50 | backgroundColor: "white",
|
51 | borderWidth: 0,
|
52 | color: "black",
|
53 | contains: [],
|
54 | drawAs: "rect",
|
55 | gpmlElementName: "Pathway",
|
56 | height: 0,
|
57 | // it appears type = {id: string} & type = {id?: string} makes id required.
|
58 | // TODO can we override that just for PathwayStarter?
|
59 | id: undefined,
|
60 | kaavioType: "Group",
|
61 | name: "New Pathway",
|
62 | // TODO what should the padding be?
|
63 | padding: 5,
|
64 | type: ["Pathway"],
|
65 | width: 0,
|
66 | x: 0,
|
67 | y: 0,
|
68 | zIndex: 0,
|
69 | // NOTE: these properties only apply contents of current element. They do not affect children.
|
70 | fontSize: 12,
|
71 | fontWeight: "bold",
|
72 | textAlign: "left",
|
73 | verticalAlign: "top"
|
74 | },
|
75 | entityMap: {}
|
76 | };
|
77 | this.graphIdManager = new GraphIdManager_1.GraphIdManager();
|
78 | this.graphIdsByGraphRef = {};
|
79 | this.containedGraphIdsByGroupGraphId = {};
|
80 | this.containedGraphIdsByGroupGroupId = {};
|
81 | this.promisedGraphIdByGroupId = {};
|
82 | this.groupIdToGraphIdStream = hl();
|
83 | this.promisedGPMLElementByGraphId = {};
|
84 | this.gpmlElementStream = hl();
|
85 | this.promisedPvjsonEntityLatestByGraphId = {};
|
86 | this.pvjsonEntityLatestStream = hl();
|
87 | this.graphIdToZIndex = {};
|
88 | this.ensureGraphIdExists = function (gpmlElement) {
|
89 | var _a = _this, containedGraphIdsByGroupGroupId = _a.containedGraphIdsByGroupGroupId, graphIdManager = _a.graphIdManager, groupIdToGraphIdStream = _a.groupIdToGraphIdStream;
|
90 | var GroupId = gpmlElement.GroupId, GroupRef = gpmlElement.GroupRef;
|
91 | var GraphId = gpmlElement.GraphId;
|
92 | // TODO does this work for all elements? Are there any that we give an id that don't have one in GPML?
|
93 | // Does the schema allow the element to have a GraphId?
|
94 | if (!!GraphId) {
|
95 | // Does it actually have one?
|
96 | if (!gpml_utilities_1.isDefinedCXML(GraphId)) {
|
97 | // NOTE: we are making sure that elements that CAN have a GraphId
|
98 | // always DO have a GraphId. GraphIds are optional in GPML for Groups,
|
99 | // so we will add one if it's not already specified. But Pathway
|
100 | // elements never have GraphIds, so we don't add one for them.
|
101 | GraphId = gpmlElement.GraphId = graphIdManager.generateAndRecord();
|
102 | }
|
103 | else {
|
104 | graphIdManager.recordExisting(GraphId);
|
105 | }
|
106 | if (gpml_utilities_1.isDefinedCXML(GroupRef)) {
|
107 | containedGraphIdsByGroupGroupId[GroupRef] =
|
108 | containedGraphIdsByGroupGroupId[GroupRef] || [];
|
109 | containedGraphIdsByGroupGroupId[GroupRef].push(GraphId);
|
110 | }
|
111 | if (gpml_utilities_1.isDefinedCXML(GroupId)) {
|
112 | groupIdToGraphIdStream.write([GroupId, GraphId]);
|
113 | }
|
114 | }
|
115 | else {
|
116 | throw new Error("GraphId missing.");
|
117 | }
|
118 | return gpmlElement;
|
119 | };
|
120 | this.fillInGPMLPropertiesFromParent = fp_1.curry(function (gpmlParentElement, gpmlChildElement) {
|
121 | var Graphics = gpmlParentElement.Graphics;
|
122 | // NOTE: this makes some assumptions about the distribution of ZOrder values in GPML
|
123 | // TODO This is what we used to do. Do we still need to do this? Or can we just sort them
|
124 | // based on whether they are burrs of each other?
|
125 | //element.zIndex = element.hasOwnProperty('zIndex') ? element.zIndex : referencedElement.zIndex + 1 / elementCount;
|
126 | var propertiesToFillIn = {
|
127 | Graphics: {
|
128 | ZOrder: Graphics.ZOrder
|
129 | }
|
130 | };
|
131 | /* TODO can we delete this?
|
132 | if (isDefinedCXML(gpmlParentElement.GroupRef)) {
|
133 | propertiesToFillIn.GroupRef = gpmlParentElement.GroupRef;
|
134 | }
|
135 | //*/
|
136 | return lodash_1.defaultsDeep(gpmlChildElement, propertiesToFillIn);
|
137 | });
|
138 | this.getPvjsonEntityLatestByGraphId = function (graphId) {
|
139 | var promisedPvjsonEntity = _this.promisedPvjsonEntityLatestByGraphId[graphId];
|
140 | if (promisedPvjsonEntity) {
|
141 | return promisedPvjsonEntity;
|
142 | }
|
143 | else {
|
144 | var pvjsonEntityLatestStream_1 = _this.pvjsonEntityLatestStream;
|
145 | // NOTE: we don't need to set the cache here, because the cache is
|
146 | // set for every item that flows through pvjsonEntityLatestStream
|
147 | promisedPvjsonEntity = new Promise(function (resolve, reject) {
|
148 | pvjsonEntityLatestStream_1
|
149 | .observe()
|
150 | .find(function (pvjsonEntity) { return pvjsonEntity.id === graphId; })
|
151 | .errors(reject)
|
152 | .each(resolve);
|
153 | });
|
154 | return promisedPvjsonEntity;
|
155 | }
|
156 | };
|
157 | this.getGPMLElementByGraphId = function (GraphId) {
|
158 | var promisedGPMLElement = _this.promisedGPMLElementByGraphId[GraphId];
|
159 | if (promisedGPMLElement) {
|
160 | return promisedGPMLElement;
|
161 | }
|
162 | else {
|
163 | var gpmlElementStream_1 = _this.gpmlElementStream;
|
164 | // NOTE: we don't need to set the cache here, because the cache is
|
165 | // set for every item that flows through gpmlElementStream
|
166 | promisedGPMLElement = new Promise(function (resolve, reject) {
|
167 | gpmlElementStream_1
|
168 | .observe()
|
169 | .find(function (gpmlElement) { return gpmlElement.GraphId === GraphId; })
|
170 | .errors(reject)
|
171 | .each(resolve);
|
172 | });
|
173 | return promisedGPMLElement;
|
174 | }
|
175 | };
|
176 | this.preprocessGPMLElement = function (gpmlElement) {
|
177 | var _a = _this, ensureGraphIdExists = _a.ensureGraphIdExists, gpmlElementStream = _a.gpmlElementStream;
|
178 | var processedGPMLElement = ensureGraphIdExists(gpmlElement);
|
179 | // NOTE: side effect
|
180 | gpmlElementStream.write(processedGPMLElement);
|
181 | return processedGPMLElement;
|
182 | };
|
183 | this.processGPMLAndPropertiesAndType = fp_1.curry(function (gpmlElementName, gpmlElement) {
|
184 | var _a = _this, preprocessGPMLElement = _a.preprocessGPMLElement, processPropertiesAndType = _a.processPropertiesAndType, pvjsonEntityLatestStream = _a.pvjsonEntityLatestStream;
|
185 | return processPropertiesAndType(gpmlElementName, preprocessGPMLElement(gpmlElement));
|
186 | });
|
187 | this.processProperties = fp_1.curry(function (gpmlElement) {
|
188 | var processKV = _this.processKV;
|
189 | var entity = fp_1.fromPairs(fp_1.toPairsIn(gpmlElement).reduce(function (acc, x) { return fp_1.concat(acc, processKV(gpmlElement, x)); }, []));
|
190 | if (!!entity.rotation) {
|
191 | entity.textRotation = -1 * entity.rotation;
|
192 | }
|
193 | return entity;
|
194 | });
|
195 | this.processPropertiesAndType = fp_1.curry(function (gpmlElementName, gpmlElement) {
|
196 | var pvjsonEntity = _this.processType(gpmlElementName, _this.processProperties(gpmlElement));
|
197 | _this.pvjsonEntityLatestStream.write(pvjsonEntity);
|
198 | return pvjsonEntity;
|
199 | });
|
200 | this.processType = fp_1.curry(function (gpmlElementName, processed) {
|
201 | var kaavioType = GPML_ELEMENT_NAME_TO_KAAVIO_TYPE[gpmlElementName];
|
202 | processed.type = gpml_utilities_1.unionLSV(processed.type, gpmlElementName, kaavioType);
|
203 | if (!!kaavioType) {
|
204 | processed.kaavioType = kaavioType;
|
205 | }
|
206 | processed.gpmlElementName = gpmlElementName;
|
207 | return processed;
|
208 | });
|
209 | this.setPvjsonEntity = function (pvjsonEntity) {
|
210 | var _a = _this, graphIdToZIndex = _a.graphIdToZIndex, promisedPvjsonEntityLatestByGraphId = _a.promisedPvjsonEntityLatestByGraphId;
|
211 | var id = pvjsonEntity.id, zIndex = pvjsonEntity.zIndex;
|
212 | graphIdToZIndex[id] = zIndex;
|
213 | promisedPvjsonEntityLatestByGraphId[id] = Promise.resolve(pvjsonEntity);
|
214 | _this.output = iassign(_this.output, function (o) {
|
215 | return o.entityMap;
|
216 | }, function (entityMap) {
|
217 | entityMap[pvjsonEntity.id] = pvjsonEntity;
|
218 | return entityMap;
|
219 | });
|
220 | };
|
221 | this.getGPMLKeyAsJSFunctionName = function (gpmlKey) {
|
222 | // NOTE: gpmlKeyAsJSFunctionName is for attributes like "Data-Source", because
|
223 | // the following would be invalid JS:
|
224 | // export function Data-Source() {};
|
225 | // TODO what about things like spaces, etc.?
|
226 | return gpmlKey.replace("-", "");
|
227 | };
|
228 | this.getPvjsonValue = function (gpmlElement, gpmlKey, gpmlValue) {
|
229 | var _a = _this, getGPMLKeyAsJSFunctionName = _a.getGPMLKeyAsJSFunctionName, getPvjsonValue = _a.getPvjsonValue, processKV = _a.processKV, ValueConverters = _a.ValueConverters, ValueMappings = _a.ValueMappings;
|
230 | var gpmlKeyAsJSFunctionName = getGPMLKeyAsJSFunctionName(gpmlKey);
|
231 | var pvjsonValue;
|
232 | try {
|
233 | if (ValueConverters.hasOwnProperty(gpmlKeyAsJSFunctionName)) {
|
234 | return ValueConverters[gpmlKeyAsJSFunctionName](gpmlElement);
|
235 | }
|
236 | else if (isStringTS(gpmlValue)) {
|
237 | if (ValueMappings.hasOwnProperty(gpmlValue)) {
|
238 | return ValueMappings[gpmlValue];
|
239 | }
|
240 | else {
|
241 | return gpmlValue;
|
242 | }
|
243 | }
|
244 | else if (isArrayTS(gpmlValue)) {
|
245 | return gpmlValue.map(function (valueItem) {
|
246 | return getPvjsonValue(valueItem, gpmlKey, valueItem);
|
247 | });
|
248 | }
|
249 | else if (isRecord(gpmlValue)) {
|
250 | return fp_1.fromPairs(fp_1.toPairsIn(gpmlValue).reduce(function (acc, _a) {
|
251 | var key = _a[0], value = _a[1];
|
252 | processKV(gpmlValue, [key, value]).forEach(function (x) {
|
253 | acc.push(x);
|
254 | });
|
255 | return acc;
|
256 | }, []));
|
257 | }
|
258 | else {
|
259 | return gpmlValue;
|
260 | }
|
261 | }
|
262 | catch (err) {
|
263 | throw new VError(err, " when calling\n\t\t\t\tgetPvjsonValue(\n\t\t\t\t\t" + JSON.stringify(gpmlElement, null, "") + ",\n\t\t\t\t\t" + JSON.stringify(gpmlKey, null, "") + ",\n\t\t\t\t\t" + JSON.stringify(gpmlValue, null, "") + "\n\t\t\t\t)\n\t\t\t\t");
|
264 | }
|
265 | };
|
266 | this.processKV = fp_1.curry(function (gpmlElement, _a) {
|
267 | var gpmlKey = _a[0], gpmlValue = _a[1];
|
268 | try {
|
269 | var _b = _this, getGPMLKeyAsJSFunctionName = _b.getGPMLKeyAsJSFunctionName, getPvjsonValue = _b.getPvjsonValue, KeyMappings = _b.KeyMappings, KeyValueConverters = _b.KeyValueConverters, processKV_1 = _b.processKV, ValueMappings = _b.ValueMappings;
|
270 | var gpmlKeyAsJSFunctionName = getGPMLKeyAsJSFunctionName(gpmlKey);
|
271 | if (VALUES_TO_SKIP.indexOf(gpmlValue) > -1) {
|
272 | return [];
|
273 | }
|
274 | if (KeyValueConverters.hasOwnProperty(gpmlKeyAsJSFunctionName)) {
|
275 | return KeyValueConverters[gpmlKeyAsJSFunctionName](gpmlElement, KeyMappings, ValueMappings);
|
276 | }
|
277 | var pvjsonKey = KeyMappings[gpmlKey];
|
278 | // NOTE "pvjson:merge" is for elements like "Graphics", where they
|
279 | // are nested in GPML but are merged into the parent in pvjson.
|
280 | if (gpmlKey[0] === "_" ||
|
281 | pvjsonKey === "pvjson:delete" ||
|
282 | (fp_1.isObject(gpmlValue) && !gpml_utilities_1.isDefinedCXML(gpmlValue))) {
|
283 | // NOTE: we don't want to include "private" keys, such as
|
284 | // "_exists" or "_namespace".
|
285 | return [];
|
286 | }
|
287 | else if (pvjsonKey === "pvjson:merge") {
|
288 | return fp_1.toPairsIn(gpmlValue).reduce(function (acc, pair) { return fp_1.concat(acc, processKV_1(gpmlElement, pair)); }, []);
|
289 | }
|
290 | else if (pvjsonKey === "pvjson:each") {
|
291 | // NOTE: Example of what uses this is GPML Attribute.
|
292 | // (in GPML, 'Attribute' is an XML *ELEMENT* named "Attribute")
|
293 | return fp_1.toPairsIn(gpmlValue
|
294 | .filter(function (_a) {
|
295 | var Key = _a.Key, Value = _a.Value;
|
296 | return VALUES_TO_SKIP.indexOf(Value) === -1;
|
297 | })
|
298 | .map(function (_a) {
|
299 | var Key = _a.Key, Value = _a.Value;
|
300 | return processKV_1(gpmlElement, [Key, Value]);
|
301 | })
|
302 | .reduce(function (acc, _a) {
|
303 | var _b = _a[0], processedKey = _b[0], processedValue = _b[1];
|
304 | // NOTE: this looks more complicated than it needs to be,
|
305 | // but it's to handle the case where there are two or more
|
306 | // sibling Attribute elements that share the same Key.
|
307 | // I don't know of any cases of this in our actual GPML,
|
308 | // but the XSD does not require unique Keys for sibling
|
309 | // Attributes.
|
310 | if (acc.hasOwnProperty(processedKey)) {
|
311 | acc[processedKey] = gpml_utilities_1.unionLSV(acc[processedKey], processedValue);
|
312 | }
|
313 | else {
|
314 | acc[processedKey] = processedValue;
|
315 | }
|
316 | return acc;
|
317 | }, {}));
|
318 | }
|
319 | else {
|
320 | var pvjsonValue = getPvjsonValue(gpmlElement, gpmlKey, gpmlValue);
|
321 | // NOTE: we don't include key/value pairs when the value is missing
|
322 | if (VALUES_TO_SKIP.indexOf(pvjsonValue) === -1) {
|
323 | return [[pvjsonKey || fp_1.camelCase(gpmlKey), pvjsonValue]];
|
324 | }
|
325 | else {
|
326 | return [];
|
327 | }
|
328 | }
|
329 | }
|
330 | catch (err) {
|
331 | throw new VError(err, " when calling processor.processKV(\n\t\t\t\t\tgpmlElement: " + JSON.stringify(gpmlElement, null, " ") + ",\n\t\t\t\t\t[\n\t\t\t\t\t\tgpmlKey: " + gpmlKey + ",\n\t\t\t\t\t\tgpmlValue: " + JSON.stringify(gpmlValue, null, " ") + "\n\t\t\t\t\t]\n\t\t\t\t)\n\t\t\t\t");
|
332 | }
|
333 | });
|
334 | var _a = this, graphIdToZIndex = _a.graphIdToZIndex, graphIdsByGraphRef = _a.graphIdsByGraphRef, promisedGPMLElementByGraphId = _a.promisedGPMLElementByGraphId, gpmlElementStream = _a.gpmlElementStream, promisedGraphIdByGroupId = _a.promisedGraphIdByGroupId, groupIdToGraphIdStream = _a.groupIdToGraphIdStream, promisedPvjsonEntityLatestByGraphId = _a.promisedPvjsonEntityLatestByGraphId, pvjsonEntityLatestStream = _a.pvjsonEntityLatestStream;
|
335 | this.KeyMappings = KeyMappings;
|
336 | this.KeyValueConverters = KeyValueConverters;
|
337 | this.ValueMappings = ValueMappings;
|
338 | this.ValueConverters = ValueConverters;
|
339 | groupIdToGraphIdStream.each(function (_a) {
|
340 | var groupId = _a[0], graphId = _a[1];
|
341 | promisedGraphIdByGroupId[groupId] = Promise.resolve(graphId);
|
342 | });
|
343 | gpmlElementStream.each(function (gpmlElement) {
|
344 | promisedGPMLElementByGraphId[gpmlElement.GraphId] = Promise.resolve(gpmlElement);
|
345 | });
|
346 | pvjsonEntityLatestStream
|
347 | .doto(function (pvjsonEntity) {
|
348 | var id = pvjsonEntity.id, zIndex = pvjsonEntity.zIndex;
|
349 | graphIdToZIndex[id] = zIndex;
|
350 | promisedPvjsonEntityLatestByGraphId[id] = Promise.resolve(pvjsonEntity);
|
351 | })
|
352 | .errors(function (err, push) {
|
353 | push(new VError(err, " observed in pvjsonEntityLatestStream\n\t\t\t\t\t\t"));
|
354 | })
|
355 | .each(function (pvjsonEntity) { });
|
356 | /*
|
357 | TODO do we need this?
|
358 | endStream.each(function(x) {
|
359 | groupIdToGraphIdStream.end();
|
360 | gpmlElementStream.end();
|
361 | pvjsonEntityLatestStream.end();
|
362 | });
|
363 | //*/
|
364 | }
|
365 | return Processor;
|
366 | }());
|
367 | exports.Processor = Processor;
|
368 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHJvY2Vzc29yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1Byb2Nlc3Nvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHVDQUFxQztBQUNyQyx1RUFBdUU7QUFFdkUsaUNBQXVEO0FBQ3ZELGdDQWdCbUI7QUFDbkIsNkJBQStCO0FBQy9CLCtCQUFpQztBQUNqQywwQ0FBNEM7QUFDNUMsT0FBTyxDQUFDLFNBQVMsQ0FBQztJQUNoQix5RkFBeUY7SUFDekYsb0dBQW9HO0lBQ3BHLGVBQWU7SUFDZixnQkFBZ0IsRUFBRSxJQUFJO0NBQ3ZCLENBQUMsQ0FBQztBQWFILG1EQUEyRDtBQUMzRCxtREFBa0Q7QUFFbEQsSUFBTSxnQ0FBZ0MsR0FBRztJQUN2QyxNQUFNLEVBQUUsTUFBTTtJQUNkLFNBQVMsRUFBRSxVQUFVO0lBQ3JCLFFBQVEsRUFBRSxnQkFBZ0I7SUFDMUIsYUFBYSxFQUFFLE1BQU07SUFDckIsS0FBSyxFQUFFLE9BQU87SUFDZCxXQUFXLEVBQUUsTUFBTTtJQUNuQixLQUFLLEVBQUUsZ0JBQWdCO0lBQ3ZCLG1DQUFtQztJQUNuQywwQkFBMEI7SUFDMUIsS0FBSyxFQUFFLGdCQUFnQjtJQUN2QixLQUFLLEVBQUUsTUFBTTtDQUNkLENBQUM7QUFFRixJQUFNLGNBQWMsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFhN0Msa0RBQWtEO0FBQ2xELG9CQUFvQixDQUFNO0lBQ3hCLE1BQU0sQ0FBQyxhQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDckIsQ0FBQztBQUVELG1CQUFtQixDQUFNO0lBQ3ZCLE1BQU0sQ0FBQyxZQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDcEIsQ0FBQztBQUVELHNFQUFzRTtBQUN0RSxrQkFBa0IsQ0FBTTtJQUN0QixNQUFNLENBQUMsQ0FBQyxZQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksYUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3BDLENB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 |
\ | No newline at end of file |