Browse Source

Add no-else-return lint rule

Lutz Roeder 3 years ago
parent
commit
2d0fa1e11b
11 changed files with 257 additions and 292 deletions
  1. 1 0
      package.json
  2. 9 15
      source/base.js
  3. 11 13
      source/dagre.js
  4. 2 6
      source/index.js
  5. 60 62
      source/keras.js
  6. 1 3
      source/onnx.js
  7. 5 11
      source/python.js
  8. 7 9
      source/pytorch.js
  9. 1 3
      source/tf.js
  10. 147 155
      source/view.js
  11. 13 15
      source/xml.js

+ 1 - 0
package.json

@@ -49,6 +49,7 @@
             "no-console": "error",
             "no-constructor-return": "error",
             "no-duplicate-imports": "error",
+            "no-else-return": "error",
             "no-promise-executor-return": "error",
             "no-self-compare": "error",
             "no-template-curly-in-string": "error",

+ 9 - 15
source/base.js

@@ -278,9 +278,7 @@ base.Utility = class {
             if (b.isNegative) {
                 return this.negate().multiply(b.negate());
             }
-            else {
-                return this.negate().multiply(b).negate();
-            }
+            return this.negate().multiply(b).negate();
         }
         else if (b.isNegative) {
             return this.multiply(b.negate()).negate();
@@ -341,19 +339,15 @@ base.Utility = class {
                 else if (b.equals(base.Int64.min)) {
                     return base.Int64.one;
                 }
-                else {
-                    const half = base.Utility._shiftRight(a, unsigned, 1);
-                    const halfDivide = half.divide(b);
-                    approx = base.Utility._shiftLeft(halfDivide, halfDivide instanceof base.Uint64, 1);
-                    if (approx.eq(base.Int64.zero)) {
-                        return b.isNegative ? base.Int64.one : base.Int64.negativeOne;
-                    }
-                    else {
-                        remainder = a.subtract(b.multiply(approx));
-                        result = approx.add(remainder.divide(b));
-                        return result;
-                    }
+                const half = base.Utility._shiftRight(a, unsigned, 1);
+                const halfDivide = half.divide(b);
+                approx = base.Utility._shiftLeft(halfDivide, halfDivide instanceof base.Uint64, 1);
+                if (approx.eq(base.Int64.zero)) {
+                    return b.isNegative ? base.Int64.one : base.Int64.negativeOne;
                 }
+                remainder = a.subtract(b.multiply(approx));
+                result = approx.add(remainder.divide(b));
+                return result;
             }
             else if (b.equals(base.Int64.min)) {
                 return unsigned ? base.Uint64.zero : base.Int64.zero;

+ 11 - 13
source/dagre.js

@@ -1011,21 +1011,19 @@ dagre.layout = (graph, options) => {
                         if (!inV.length) {
                             return { v: v };
                         }
-                        else {
-                            const result = inV.reduce((acc, e) => {
-                                const edge = e.label;
-                                const nodeU = e.vNode.label;
-                                return {
-                                    sum: acc.sum + (edge.weight * nodeU.order),
-                                    weight: acc.weight + edge.weight
-                                };
-                            }, { sum: 0, weight: 0 });
+                        const result = inV.reduce((acc, e) => {
+                            const edge = e.label;
+                            const nodeU = e.vNode.label;
                             return {
-                                v: v,
-                                barycenter: result.sum / result.weight,
-                                weight: result.weight
+                                sum: acc.sum + (edge.weight * nodeU.order),
+                                weight: acc.weight + edge.weight
                             };
-                        }
+                        }, { sum: 0, weight: 0 });
+                        return {
+                            v: v,
+                            barycenter: result.sum / result.weight,
+                            weight: result.weight
+                        };
                     });
                 };
                 const sort = (entries, biasRight) => {

+ 2 - 6
source/index.js

@@ -940,9 +940,7 @@ if (typeof TextEncoder === 'undefined') {
         if (typeof Uint8Array!=="undefined") {
             return new Uint8Array(resArr.buffer.slice(0, resPos+1));
         }
-        else {
-            return resArr.length === resPos + 1 ? resArr : resArr.slice(0, resPos + 1);
-        }
+        return resArr.length === resPos + 1 ? resArr : resArr.slice(0, resPos + 1);
     };
     TextEncoder.prototype.toString = function() {
         return "[object TextEncoder]";
@@ -953,9 +951,7 @@ if (typeof TextEncoder === 'undefined') {
                 if (Object.prototype.isPrototypeOf.call(TextEncoder.prototype, this)) {
                     return"utf-8";
                 }
-                else {
-                    throw new TypeError("Illegal invocation");
-                }
+                throw new TypeError("Illegal invocation");
             }
         });
     }

+ 60 - 62
source/keras.js

@@ -211,76 +211,74 @@ keras.ModelFactory = class {
                         }
                         return openModel(format, '', backend, null, weights);
                     }
-                    else {
-                        const rootKeys = new Set(root_group.attributes.keys());
-                        rootKeys.delete('nb_layers');
-                        if (rootKeys.size > 0 || root_group.value !== null) {
-                            throw new keras.Error('File format is not HDF5 Weights');
-                        }
-                        const format = 'HDF5 Weights';
-                        let weights_group = root_group;
-                        if (root_group.attributes.size === 0 && root_group.value === null && root_group.groups.size == 1) {
-                            const group = root_group.groups.values().next().value;
-                            if (group.attributes.size === 0 && group.value === null) {
-                                weights_group = group;
-                            }
-                        }
-                        const tensorKeys = new Set([ 'name', 'shape', 'quantization' ]);
-                        const groups = Array.from(weights_group.groups.values());
-                        if (groups.every((group) => group.attributes.size === 0 && group.groups.length == 0 && group.value !== null)) {
-                            for (const group of groups) {
-                                const variable = group.value;
-                                const tensor = new keras.Tensor(group.name, variable.shape, variable.type, null, variable.littleEndian, variable.type === 'string' ? variable.value : variable.data);
-                                weights.add('', tensor);
-                            }
-                            return openModel(format, '', '', null, weights);
+                    const rootKeys = new Set(root_group.attributes.keys());
+                    rootKeys.delete('nb_layers');
+                    if (rootKeys.size > 0 || root_group.value !== null) {
+                        throw new keras.Error('File format is not HDF5 Weights');
+                    }
+                    const format = 'HDF5 Weights';
+                    let weights_group = root_group;
+                    if (root_group.attributes.size === 0 && root_group.value === null && root_group.groups.size == 1) {
+                        const group = root_group.groups.values().next().value;
+                        if (group.attributes.size === 0 && group.value === null) {
+                            weights_group = group;
                         }
-                        if (groups.every((group) => group.value === null && Array.from(group.attributes.keys()).filter((key) => !tensorKeys.has(key)).length === 0 && Array.from(group.groups.values()).every((variable) => Object.keys(variable.attributes).length === 0 && variable.value !== null))) {
-                            for (const group of groups) {
-                                const moduleName = group.attributes.has('name') ? group.attributes.get('name') : group.name;
-                                for (const variableGroup of group.groups.values()) {
-                                    if (variableGroup.attributes.size !== 0 || variableGroup.groups.size !== 0) {
-                                        throw new keras.Error('Variable format is not HDF5 Weights');
-                                    }
-                                    const variable = variableGroup.value;
-                                    if (!variable) {
-                                        throw new keras.Error('Variable value is not HDF5 Weights');
-                                    }
-                                    const name = moduleName ? [ moduleName, variableGroup.name ].join('/') : moduleName.name;
-                                    const tensor = new keras.Tensor(name, variable.shape, variable.type, null, variable.littleEndian, variable.type === 'string' ? variable.value : variable.data);
-                                    weights.add(moduleName, tensor);
-                                }
-                            }
-                            return openModel(format, '', '', null, weights);
+                    }
+                    const tensorKeys = new Set([ 'name', 'shape', 'quantization' ]);
+                    const groups = Array.from(weights_group.groups.values());
+                    if (groups.every((group) => group.attributes.size === 0 && group.groups.length == 0 && group.value !== null)) {
+                        for (const group of groups) {
+                            const variable = group.value;
+                            const tensor = new keras.Tensor(group.name, variable.shape, variable.type, null, variable.littleEndian, variable.type === 'string' ? variable.value : variable.data);
+                            weights.add('', tensor);
                         }
-                        const walk = function(group) {
-                            if (group.attributes.size === 0 && group.value === null && group.groups.size > 0) {
-                                for (const subGroup of group.groups.values()) {
-                                    walk(subGroup);
+                        return openModel(format, '', '', null, weights);
+                    }
+                    if (groups.every((group) => group.value === null && Array.from(group.attributes.keys()).filter((key) => !tensorKeys.has(key)).length === 0 && Array.from(group.groups.values()).every((variable) => Object.keys(variable.attributes).length === 0 && variable.value !== null))) {
+                        for (const group of groups) {
+                            const moduleName = group.attributes.has('name') ? group.attributes.get('name') : group.name;
+                            for (const variableGroup of group.groups.values()) {
+                                if (variableGroup.attributes.size !== 0 || variableGroup.groups.size !== 0) {
+                                    throw new keras.Error('Variable format is not HDF5 Weights');
                                 }
-                                return;
-                            }
-                            const subKeys = new Set([ 'index', 'need_grad' ]);
-                            const attribtues = Array.from(group.attributes.keys());
-                            const match = attribtues.filter((key) => !subKeys.has(key)).length === 0;
-                            if (match && group.value !== null && group.groups.size === 0) {
-                                const variable = group.value;
-                                const variableName = group.path;
-                                let moduleName = variableName;
-                                const parts = variableName.split('/');
-                                if (parts.length > 1) {
-                                    parts.pop();
-                                    moduleName = parts.join('/');
+                                const variable = variableGroup.value;
+                                if (!variable) {
+                                    throw new keras.Error('Variable value is not HDF5 Weights');
                                 }
-                                const tensor = new keras.Tensor(variableName, variable.shape, variable.type, null, variable.littleEndian, variable.type === 'string' ? variable.value : variable.data);
+                                const name = moduleName ? [ moduleName, variableGroup.name ].join('/') : moduleName.name;
+                                const tensor = new keras.Tensor(name, variable.shape, variable.type, null, variable.littleEndian, variable.type === 'string' ? variable.value : variable.data);
                                 weights.add(moduleName, tensor);
-                                return;
                             }
-                            throw new keras.Error('Module group format is not HDF5 Weights');
-                        };
-                        walk(weights_group);
+                        }
                         return openModel(format, '', '', null, weights);
                     }
+                    const walk = function(group) {
+                        if (group.attributes.size === 0 && group.value === null && group.groups.size > 0) {
+                            for (const subGroup of group.groups.values()) {
+                                walk(subGroup);
+                            }
+                            return;
+                        }
+                        const subKeys = new Set([ 'index', 'need_grad' ]);
+                        const attribtues = Array.from(group.attributes.keys());
+                        const match = attribtues.filter((key) => !subKeys.has(key)).length === 0;
+                        if (match && group.value !== null && group.groups.size === 0) {
+                            const variable = group.value;
+                            const variableName = group.path;
+                            let moduleName = variableName;
+                            const parts = variableName.split('/');
+                            if (parts.length > 1) {
+                                parts.pop();
+                                moduleName = parts.join('/');
+                            }
+                            const tensor = new keras.Tensor(variableName, variable.shape, variable.type, null, variable.littleEndian, variable.type === 'string' ? variable.value : variable.data);
+                            weights.add(moduleName, tensor);
+                            return;
+                        }
+                        throw new keras.Error('Module group format is not HDF5 Weights');
+                    };
+                    walk(weights_group);
+                    return openModel(format, '', '', null, weights);
                 });
             }
             case 'keras.json': {

+ 1 - 3
source/onnx.js

@@ -77,9 +77,7 @@ onnx.ModelFactory = class {
                                 if (value === number) {
                                     return type === 2 ? reader.bytes() : null;
                                 }
-                                else {
-                                    reader.skipType(type);
-                                }
+                                reader.skipType(type);
                             }
                             return null;
                         };

+ 5 - 11
source/python.js

@@ -1896,10 +1896,8 @@ python.Execution = class {
                 if (this.dtype.__name__ == 'object') {
                     return unpickler.load((name, args) => self.invoke(name, args), null);
                 }
-                else {
-                    const size = this.dtype.itemsize * this.shape.reduce((a, b) => a * b, 1);
-                    this.data = unpickler.read(size);
-                }
+                const size = this.dtype.itemsize * this.shape.reduce((a, b) => a * b, 1);
+                this.data = unpickler.read(size);
                 return self.invoke(this.subclass, [ this.shape, this.dtype, this.data ]);
             }
         });
@@ -2121,10 +2119,8 @@ python.Execution = class {
                 if (this.dtype.__name__ == 'object') {
                     return unpickler.load((name, args) => self.invoke(name, args), null);
                 }
-                else {
-                    const size = this.dtype.itemsize * this.shape.reduce((a, b) => a * b, 1);
-                    this.data = unpickler.read(size);
-                }
+                const size = this.dtype.itemsize * this.shape.reduce((a, b) => a * b, 1);
+                this.data = unpickler.read(size);
                 return self.invoke(this.subclass, [ this.shape, this.dtype, this.data ]);
             }
         });
@@ -2914,9 +2910,7 @@ python.Execution = class {
                 if (target.__call__) {
                     return target.__call__(args);
                 }
-                else {
-                    return target.apply(null, args);
-                }
+                return target.apply(null, args);
             }
         }
         this._raiseUnkownName(name);

+ 7 - 9
source/pytorch.js

@@ -4451,15 +4451,13 @@ pytorch.Metadata = class {
         if (pytorch.Metadata._metadata) {
             return Promise.resolve(pytorch.Metadata._metadata);
         }
-        else {
-            return context.request('pytorch-metadata.json', 'utf-8', null).then((data) => {
-                pytorch.Metadata._metadata = new pytorch.Metadata(data);
-                return pytorch.Metadata._metadata;
-            }).catch(() => {
-                pytorch.Metadata._metadata = new pytorch.Metadata(null);
-                return pytorch.Metadata._metadata;
-            });
-        }
+        return context.request('pytorch-metadata.json', 'utf-8', null).then((data) => {
+            pytorch.Metadata._metadata = new pytorch.Metadata(data);
+            return pytorch.Metadata._metadata;
+        }).catch(() => {
+            pytorch.Metadata._metadata = new pytorch.Metadata(null);
+            return pytorch.Metadata._metadata;
+        });
     }
 
     constructor(data) {

+ 1 - 3
source/tf.js

@@ -138,9 +138,7 @@ tf.ModelFactory = class {
                             if (value === number) {
                                 return type === 2 ? reader.bytes() : null;
                             }
-                            else {
-                                reader.skipType(type);
-                            }
+                            reader.skipType(type);
                         }
                         return null;
                     };

+ 147 - 155
source/view.js

@@ -532,106 +532,104 @@ view.View = class {
             if (!graph) {
                 return Promise.resolve();
             }
-            else {
-                this._zoom = 1;
-
-                const groups = graph.groups;
-                const nodes = graph.nodes;
-                this._host.event('Graph', 'Render', 'Size', nodes.length);
-
-                const options = {};
-                options.nodesep = 20;
-                options.ranksep = 20;
-                const rotate = graph.nodes.every((node) => node.inputs.filter((input) => input.arguments.every((argument) => !argument.initializer)).length === 0 && node.outputs.length === 0);
-                const horizontal = rotate ? this._options.direction === 'vertical' : this._options.direction !== 'vertical';
-                if (horizontal) {
-                    options.rankdir = "LR";
-                }
-                if (nodes.length > 3000) {
-                    options.ranker = 'longest-path';
-                }
+            this._zoom = 1;
+
+            const groups = graph.groups;
+            const nodes = graph.nodes;
+            this._host.event('Graph', 'Render', 'Size', nodes.length);
+
+            const options = {};
+            options.nodesep = 20;
+            options.ranksep = 20;
+            const rotate = graph.nodes.every((node) => node.inputs.filter((input) => input.arguments.every((argument) => !argument.initializer)).length === 0 && node.outputs.length === 0);
+            const horizontal = rotate ? this._options.direction === 'vertical' : this._options.direction !== 'vertical';
+            if (horizontal) {
+                options.rankdir = "LR";
+            }
+            if (nodes.length > 3000) {
+                options.ranker = 'longest-path';
+            }
 
-                const viewGraph = new view.Graph(this, model, groups, options);
-                viewGraph.add(graph);
+            const viewGraph = new view.Graph(this, model, groups, options);
+            viewGraph.add(graph);
 
-                // Workaround for Safari background drag/zoom issue:
-                // https://stackoverflow.com/questions/40887193/d3-js-zoom-is-not-working-with-mousewheel-in-safari
-                const background = this._host.document.createElementNS('http://www.w3.org/2000/svg', 'rect');
-                background.setAttribute('id', 'background');
-                background.setAttribute('fill', 'none');
-                background.setAttribute('pointer-events', 'all');
-                canvas.appendChild(background);
+            // Workaround for Safari background drag/zoom issue:
+            // https://stackoverflow.com/questions/40887193/d3-js-zoom-is-not-working-with-mousewheel-in-safari
+            const background = this._host.document.createElementNS('http://www.w3.org/2000/svg', 'rect');
+            background.setAttribute('id', 'background');
+            background.setAttribute('fill', 'none');
+            background.setAttribute('pointer-events', 'all');
+            canvas.appendChild(background);
 
-                const origin = this._host.document.createElementNS('http://www.w3.org/2000/svg', 'g');
-                origin.setAttribute('id', 'origin');
-                canvas.appendChild(origin);
+            const origin = this._host.document.createElementNS('http://www.w3.org/2000/svg', 'g');
+            origin.setAttribute('id', 'origin');
+            canvas.appendChild(origin);
 
-                viewGraph.build(this._host.document, origin);
+            viewGraph.build(this._host.document, origin);
 
-                this._zoom = 1;
+            this._zoom = 1;
 
-                return this._timeout(20).then(() => {
+            return this._timeout(20).then(() => {
 
-                    viewGraph.update();
+                viewGraph.update();
 
-                    const elements = Array.from(canvas.getElementsByClassName('graph-input') || []);
-                    if (elements.length === 0) {
-                        const nodeElements = Array.from(canvas.getElementsByClassName('graph-node') || []);
-                        if (nodeElements.length > 0) {
-                            elements.push(nodeElements[0]);
-                        }
+                const elements = Array.from(canvas.getElementsByClassName('graph-input') || []);
+                if (elements.length === 0) {
+                    const nodeElements = Array.from(canvas.getElementsByClassName('graph-node') || []);
+                    if (nodeElements.length > 0) {
+                        elements.push(nodeElements[0]);
                     }
+                }
 
-                    const size = canvas.getBBox();
-                    const margin = 100;
-                    const width = Math.ceil(margin + size.width + margin);
-                    const height = Math.ceil(margin + size.height + margin);
-                    origin.setAttribute('transform', 'translate(' + margin.toString() + ', ' + margin.toString() + ') scale(1)');
-                    background.setAttribute('width', width);
-                    background.setAttribute('height', height);
-                    this._width = width;
-                    this._height = height;
-                    delete this._scrollLeft;
-                    delete this._scrollRight;
-                    canvas.setAttribute('viewBox', '0 0 ' + width + ' ' + height);
-                    canvas.setAttribute('width', width);
-                    canvas.setAttribute('height', height);
-
-                    this._zoom = 1;
-                    this._updateZoom(this._zoom);
+                const size = canvas.getBBox();
+                const margin = 100;
+                const width = Math.ceil(margin + size.width + margin);
+                const height = Math.ceil(margin + size.height + margin);
+                origin.setAttribute('transform', 'translate(' + margin.toString() + ', ' + margin.toString() + ') scale(1)');
+                background.setAttribute('width', width);
+                background.setAttribute('height', height);
+                this._width = width;
+                this._height = height;
+                delete this._scrollLeft;
+                delete this._scrollRight;
+                canvas.setAttribute('viewBox', '0 0 ' + width + ' ' + height);
+                canvas.setAttribute('width', width);
+                canvas.setAttribute('height', height);
 
-                    const container = this._getElementById('graph');
-                    if (elements && elements.length > 0) {
-                        // Center view based on input elements
-                        const xs = [];
-                        const ys = [];
-                        for (let i = 0; i < elements.length; i++) {
-                            const element = elements[i];
-                            const rect = element.getBoundingClientRect();
-                            xs.push(rect.left + (rect.width / 2));
-                            ys.push(rect.top + (rect.height / 2));
-                        }
-                        let x = xs[0];
-                        const y = ys[0];
-                        if (ys.every(y => y === ys[0])) {
-                            x = xs.reduce((a, b) => a + b, 0) / xs.length;
-                        }
-                        const graphRect = container.getBoundingClientRect();
-                        const left = (container.scrollLeft + x - graphRect.left) - (graphRect.width / 2);
-                        const top = (container.scrollTop + y - graphRect.top) - (graphRect.height / 2);
-                        container.scrollTo({ left: left, top: top, behavior: 'auto' });
+                this._zoom = 1;
+                this._updateZoom(this._zoom);
+
+                const container = this._getElementById('graph');
+                if (elements && elements.length > 0) {
+                    // Center view based on input elements
+                    const xs = [];
+                    const ys = [];
+                    for (let i = 0; i < elements.length; i++) {
+                        const element = elements[i];
+                        const rect = element.getBoundingClientRect();
+                        xs.push(rect.left + (rect.width / 2));
+                        ys.push(rect.top + (rect.height / 2));
                     }
-                    else {
-                        const canvasRect = canvas.getBoundingClientRect();
-                        const graphRect = container.getBoundingClientRect();
-                        const left = (container.scrollLeft + (canvasRect.width / 2) - graphRect.left) - (graphRect.width / 2);
-                        const top = (container.scrollTop + (canvasRect.height / 2) - graphRect.top) - (graphRect.height / 2);
-                        container.scrollTo({ left: left, top: top, behavior: 'auto' });
+                    let x = xs[0];
+                    const y = ys[0];
+                    if (ys.every(y => y === ys[0])) {
+                        x = xs.reduce((a, b) => a + b, 0) / xs.length;
                     }
-                    this._graph = viewGraph;
-                    return;
-                });
-            }
+                    const graphRect = container.getBoundingClientRect();
+                    const left = (container.scrollLeft + x - graphRect.left) - (graphRect.width / 2);
+                    const top = (container.scrollTop + y - graphRect.top) - (graphRect.height / 2);
+                    container.scrollTo({ left: left, top: top, behavior: 'auto' });
+                }
+                else {
+                    const canvasRect = canvas.getBoundingClientRect();
+                    const graphRect = container.getBoundingClientRect();
+                    const left = (container.scrollLeft + (canvasRect.width / 2) - graphRect.left) - (graphRect.width / 2);
+                    const top = (container.scrollTop + (canvasRect.height / 2) - graphRect.top) - (graphRect.height / 2);
+                    container.scrollTo({ left: left, top: top, behavior: 'auto' });
+                }
+                this._graph = viewGraph;
+                return;
+            });
         }
         catch (error) {
             return Promise.reject(error);
@@ -1874,16 +1872,14 @@ view.ModelFactoryService = class {
                     });
                 });
             }
-            else {
-                if (success) {
-                    if (errors.length === 1) {
-                        const error = errors[0];
-                        return Promise.reject(error);
-                    }
-                    return Promise.reject(new view.Error(errors.map((err) => err.message).join('\n')));
+            if (success) {
+                if (errors.length === 1) {
+                    const error = errors[0];
+                    return Promise.reject(error);
                 }
-                return Promise.resolve(null);
+                return Promise.reject(new view.Error(errors.map((err) => err.message).join('\n')));
             }
+            return Promise.resolve(null);
         };
         return nextModule();
     }
@@ -1920,70 +1916,66 @@ view.ModelFactoryService = class {
                                     return nextModule();
                                 });
                             }
-                            else {
-                                return nextEntry();
-                            }
+                            return nextEntry();
                         };
                         return nextModule();
                     }
-                    else {
-                        if (matches.length === 0) {
-                            return Promise.resolve(null);
-                        }
-                        // MXNet
-                        if (matches.length === 2 &&
-                            matches.some((e) => e.name.toLowerCase().endsWith('.params')) &&
-                            matches.some((e) => e.name.toLowerCase().endsWith('-symbol.json'))) {
-                            matches = matches.filter((e) => e.name.toLowerCase().endsWith('.params'));
-                        }
-                        // TensorFlow.js
-                        if (matches.length > 0 &&
-                            matches.some((e) => e.name.toLowerCase().endsWith('.bin')) &&
-                            matches.some((e) => e.name.toLowerCase().endsWith('.json'))) {
-                            matches = matches.filter((e) => e.name.toLowerCase().endsWith('.json'));
-                        }
-                        // ncnn
-                        if (matches.length > 0 &&
-                            matches.some((e) => e.name.toLowerCase().endsWith('.bin')) &&
-                            matches.some((e) => e.name.toLowerCase().endsWith('.param'))) {
-                            matches = matches.filter((e) => e.name.toLowerCase().endsWith('.param'));
-                        }
-                        // ncnn
-                        if (matches.length > 0 &&
-                            matches.some((e) => e.name.toLowerCase().endsWith('.bin')) &&
-                            matches.some((e) => e.name.toLowerCase().endsWith('.param.bin'))) {
-                            matches = matches.filter((e) => e.name.toLowerCase().endsWith('.param.bin'));
-                        }
-                        // Paddle
-                        if (matches.length > 0 &&
-                            matches.some((e) => e.name.toLowerCase().endsWith('.pdmodel')) &&
-                            (matches.some((e) => e.name.toLowerCase().endsWith('.pdparams')) ||
-                             matches.some((e) => e.name.toLowerCase().endsWith('.pdopt')) ||
-                             matches.some((e) => e.name.toLowerCase().endsWith('.pdiparams')))) {
-                            matches = matches.filter((e) => e.name.toLowerCase().endsWith('.pdmodel'));
-                        }
-                        // Paddle Lite
-                        if (matches.length > 0 &&
-                            matches.some((e) => e.name.toLowerCase().split('/').pop() === '__model__.nb') &&
-                            matches.some((e) => e.name.toLowerCase().split('/').pop() === 'param.nb')) {
-                            matches = matches.filter((e) => e.name.toLowerCase().split('/').pop() == '__model__.nb');
-                        }
-                        // TensorFlow Bundle
-                        if (matches.length > 1 &&
-                            matches.some((e) => e.name.toLowerCase().endsWith('.data-00000-of-00001'))) {
-                            matches = matches.filter((e) => !e.name.toLowerCase().endsWith('.data-00000-of-00001'));
-                        }
-                        // TensorFlow SavedModel
-                        if (matches.length === 2 &&
-                            matches.some((e) => e.name.toLowerCase().split('/').pop() === 'keras_metadata.pb')) {
-                            matches = matches.filter((e) => e.name.toLowerCase().split('/').pop() !== 'keras_metadata.pb');
-                        }
-                        if (matches.length > 1) {
-                            return Promise.reject(new view.ArchiveError('Archive contains multiple model files.'));
-                        }
-                        const match = matches.shift();
-                        return Promise.resolve(new view.ModelContext(new view.ArchiveContext(this._host, entries, folder, match.name, match.stream)));
+                    if (matches.length === 0) {
+                        return Promise.resolve(null);
+                    }
+                    // MXNet
+                    if (matches.length === 2 &&
+                        matches.some((e) => e.name.toLowerCase().endsWith('.params')) &&
+                        matches.some((e) => e.name.toLowerCase().endsWith('-symbol.json'))) {
+                        matches = matches.filter((e) => e.name.toLowerCase().endsWith('.params'));
+                    }
+                    // TensorFlow.js
+                    if (matches.length > 0 &&
+                        matches.some((e) => e.name.toLowerCase().endsWith('.bin')) &&
+                        matches.some((e) => e.name.toLowerCase().endsWith('.json'))) {
+                        matches = matches.filter((e) => e.name.toLowerCase().endsWith('.json'));
+                    }
+                    // ncnn
+                    if (matches.length > 0 &&
+                        matches.some((e) => e.name.toLowerCase().endsWith('.bin')) &&
+                        matches.some((e) => e.name.toLowerCase().endsWith('.param'))) {
+                        matches = matches.filter((e) => e.name.toLowerCase().endsWith('.param'));
+                    }
+                    // ncnn
+                    if (matches.length > 0 &&
+                        matches.some((e) => e.name.toLowerCase().endsWith('.bin')) &&
+                        matches.some((e) => e.name.toLowerCase().endsWith('.param.bin'))) {
+                        matches = matches.filter((e) => e.name.toLowerCase().endsWith('.param.bin'));
+                    }
+                    // Paddle
+                    if (matches.length > 0 &&
+                        matches.some((e) => e.name.toLowerCase().endsWith('.pdmodel')) &&
+                        (matches.some((e) => e.name.toLowerCase().endsWith('.pdparams')) ||
+                            matches.some((e) => e.name.toLowerCase().endsWith('.pdopt')) ||
+                            matches.some((e) => e.name.toLowerCase().endsWith('.pdiparams')))) {
+                        matches = matches.filter((e) => e.name.toLowerCase().endsWith('.pdmodel'));
+                    }
+                    // Paddle Lite
+                    if (matches.length > 0 &&
+                        matches.some((e) => e.name.toLowerCase().split('/').pop() === '__model__.nb') &&
+                        matches.some((e) => e.name.toLowerCase().split('/').pop() === 'param.nb')) {
+                        matches = matches.filter((e) => e.name.toLowerCase().split('/').pop() == '__model__.nb');
+                    }
+                    // TensorFlow Bundle
+                    if (matches.length > 1 &&
+                        matches.some((e) => e.name.toLowerCase().endsWith('.data-00000-of-00001'))) {
+                        matches = matches.filter((e) => !e.name.toLowerCase().endsWith('.data-00000-of-00001'));
+                    }
+                    // TensorFlow SavedModel
+                    if (matches.length === 2 &&
+                        matches.some((e) => e.name.toLowerCase().split('/').pop() === 'keras_metadata.pb')) {
+                        matches = matches.filter((e) => e.name.toLowerCase().split('/').pop() !== 'keras_metadata.pb');
+                    }
+                    if (matches.length > 1) {
+                        return Promise.reject(new view.ArchiveError('Archive contains multiple model files.'));
                     }
+                    const match = matches.shift();
+                    return Promise.resolve(new view.ModelContext(new view.ArchiveContext(this._host, entries, folder, match.name, match.stream)));
                 };
                 return nextEntry();
             };

+ 13 - 15
source/xml.js

@@ -902,7 +902,7 @@ xml.TextReader = class {
 
     _resolveEntityReference() {
         const position = this._position;
-        const entity = this._entityReference();
+        let entity = this._entityReference();
         const name = entity.substring(1, entity.length - 1);
         if (name.startsWith('#x')) {
             const value = parseInt(name.substring(2), 16);
@@ -915,24 +915,22 @@ xml.TextReader = class {
         else if (this._entities.has(name)) {
             return this._entities.get(name);
         }
-        else {
-            const documentType = this._document().documentType;
-            const entity = documentType ? documentType.entities.getNamedItem(name) : null;
-            if (entity) {
-                if (entity.systemId) {
-                    this._pushResource(entity.systemId, name, true);
-                }
-                else {
-                    this._pushString(entity.value, name, true);
-                }
+        const documentType = this._document().documentType;
+        entity = documentType ? documentType.entities.getNamedItem(name) : null;
+        if (entity) {
+            if (entity.systemId) {
+                this._pushResource(entity.systemId, name, true);
             }
             else {
-                if (this._context.length !== 0 || !documentType || documentType.parameterEntities.length === 0) {
-                    this._error("Undefined ENTITY '" + name + "'", position);
-                }
+                this._pushString(entity.value, name, true);
+            }
+        }
+        else {
+            if (this._context.length !== 0 || !documentType || documentType.parameterEntities.length === 0) {
+                this._error("Undefined ENTITY '" + name + "'", position);
             }
-            return undefined;
         }
+        return undefined;
     }
 
     /* eslint-disable consistent-return */