<commit_before>
var IvxBtn = Ivx.extend(Phaser.Button,'PSprite', function(group, idx, onclick) {
    var game, x, y, thisObj, bgIdx, activeIdx, spriteIdx, scale, mag;
    x = 20+ (120 * idx);
    game = group.game;

    bgIdx = 0;
    activeIdx = 1;
    spriteIdx = idx + 2;

    thisObj = this;
    Phaser.Button.call(this, group.game, x, y, 'ui', function() {
        onclick();
    },
    bgIdx, bgIdx, bgIdx);
    group.add(this);

    this.onInputDown.add(function() {
       thisObj.eventInputDown(idx);
    });
    this.onInputUp.add(function() {
        thisObj.eventInputUp(idx);
    });

    this.active = new Phaser.Sprite(game, 0, 0, 'ui', activeIdx);
    this.icon = new Phaser.Sprite(game, 0, 0, 'ui', spriteIdx);
    this.addChild(this.active);
    this.addChild(this.icon);
    this.active.visible = false;

});
IvxBtn.prototype.eventClicked = function(idx) {
    //console.log('eventClicked: ' + idx);
};
IvxBtn.prototype.eventInputDown = function(idx) {
    //console.log('eventInputDown: ' + idx);
    this.active.visible = true;
};
IvxBtn.prototype.eventInputUp = function(idx) {
    //console.log('eventInputUp: ' + idx);
    this.active.visible = false;
};

var IvxTile = Ivx.extend(Phaser.Sprite,'PSprite', function(group) {
    var thisObj, board, col, row, x, y, midpoint, mag, rect;

    board = group.board;

    this.idx = group.cellArr.length;

    col = this.idx % board.cols;
    row = (this.idx / board.cols)|0;

    x = col * (board.size);
    y = row * (board.size);
    //console.log('IvxTile: idx: ' + this.idx + ' col: ' + col + ' row: ' + row + ' x: ' + x + ' y:'+y);

    Phaser.Sprite.call(this, group.game, x, y, 'pscaled', this.idx);

    midpoint = (board.size)/2|0;

    this.x = board.offx + ((midpoint + col * board.size ) );
    this.y = board.offy + ((midpoint + row * board.size ) );

    this.anchor.setTo(0.5);

    this.inputEnabled = true;
    this.input.enableDrag();

    thisObj = this;
    this.events.onDragStart.add(function(sprite, pointer) {

        thisObj.eventDragStart(sprite, pointer);
    });
    this.events.onDragStop.add(function(sprite, pointer) {
        thisObj.eventDragStop(sprite, pointer);
    });

    group.add(this);
    group.cellArr.push(this);

    //this.visible  = false;

    this.orig = {
        mag: mag,
        txt: this.texture,
        angle: this.angle,
        scalex: this.scale.x,
        scaley: this.scale.y,
        x: this.x,
        y: this.y,
        tint: this.tint
    };

});
IvxTile.prototype.isCorrect = function () {
    var o, correct;
    o = this.orig;

    if (this.scale.x < 0 && this.scale.y < 0) {
        this.scale.x *= -1;
        this.scale.y *= -1;
        this.angle += 180;
    }

    correct =  (!this.angle) && (this.x === o.x) && (this.y === o.y) &&  (this.texture === o.txt);
    correct = correct && (this.scale.x === o.scalex) && (this.scale.y === o.scaley)

    return correct;
};

IvxTile.prototype.isActive = function () {
    return this === this.parent.active;
};
IvxTile.prototype.adjustTint = function () {
    if (this.isCorrect()) {
       this.tint = this.orig.tint && 0xffffff;
    } else {
       if (this.isActive()) {
            this.tint = this.orig.tint && 0x55ff55;
       } else {
           this.tint = this.orig.tint && 0xff8888;
       }
    }
};

IvxTile.prototype.checkCorrect = function (animate) {
    var correct;

    correct = this.isCorrect();
    if (correct) {
       this.inputEnabled = false;
       if (this.isActive()) {
        this.parent.active = null;
        this.parent.eventActive(false);
       }
    }
    this.adjustTint();
    return correct;
};

IvxTile.prototype.swap = function (tile) {

    var swap;
    swap =  { txt: tile.texture,  angle: tile.angle, scalex: tile.scale.x, scaley: tile.scale.y };

    tile.texture = this.texture;
    tile.angle = this.angle;
    tile.scale.x = this.scale.x;
    tile.scale.y = this.scale.y;

    this.texture = swap.txt;
    this.angle = swap.angle;
    this.scale.x = swap.scalex;
    this.scale.y = swap.scaley;

};
IvxTile.prototype.tileIdx = function (idx) {
    return this.parent.cellArr[idx];
};
IvxTile.prototype.swapIdx = function (idx) {
    var tile;
    tile = this.parent.cellArr[idx];
    this.swap(tile);
    return tile;
};
IvxTile.prototype.calcIdx = function() {
    var col, row, idx, tile, board, size;

    size = Math.abs(this.width);
    board = this.parent.board;

    col = ((this.x - board.offx ) / size)|0;
    row = ((this.y - board.offy ) / size)|0;
    if ( (col+1) > board.cols || (row+1) > board.rows || col < 0 || row < 0) {
        return this.idx;
    }

    idx = col + row * board.cols;

    if (idx < this.parent.cellArr.length) {
        tile = this.tileIdx(idx);
        if (tile.isCorrect()) {
            return this.idx;
        }
        return idx;
    }
    return this.idx;
};
IvxTile.prototype.eventDragStart = function (sprite, pointer) {

    this.origActive =  this.parent.active;
    this.parent.eventActive(false);

    this.parent.active = this;

    this.last = { x: this.x, y: this.y, type: this.position.type};
    this.bringToTop();
};
IvxTile.prototype.eventDragStop = function (sprite, pointer) {

    var idx, tile;

    idx = this.calcIdx();

    tile = this.swapIdx(idx);
    this.x = this.last.x;
    this.y = this.last.y;
    if (this !== tile) {
        this.parent.active = tile;
        this.checkCorrect();
    } else {
        if (this.origActive === this) {
            this.parent.active = null;
        }
    }
    this.parent.eventActive(this.parent.active);

    tile.checkCorrect(true) && this.parent.checkComplete();

};
IvxTile.prototype._turn = function () {

    this.parent.tween = null;
    this.parent.eventActive(true);
    this.checkCorrect(true) && this.parent.checkComplete();

};
IvxTile.prototype.turnRight = function () {
    var thisObj, angle, parent;

    thisObj = this;
    angle = this.angle + 90;

    parent = this.parent
    parent.eventActive(false);
    parent.tween =this.game.add.tween(this);
    parent.tween.to({angle: angle}, ivxCfg.tweenTIME , Phaser.Easing.Linear.None, true);
    parent.tween.onComplete.addOnce(function() {thisObj._turn();}, this);
};
IvxTile.prototype.turnLeft = function () {
    var thisObj, angle, parent;

    thisObj = this;
    angle = this.angle - 90;

    parent = this.parent
    parent.eventActive(false);
    parent.tween =this.game.add.tween(this);
    parent.tween.to({angle: angle}, ivxCfg.tweenTIME , Phaser.Easing.Linear.None, true);
    parent.tween.onComplete.addOnce(function() {thisObj._turn();}, this);

};
IvxTile.prototype.flipH = function () {
    var thisObj, parent, val;

    val = this.scale.x * -1;

    thisObj = this;
    parent = this.parent
    parent.eventActive(false);
    parent.tween =this.game.add.tween(this.scale);
    parent.tween.to({x: val}, ivxCfg.tweenTIME , Phaser.Easing.Linear.None, true);
    parent.tween.onComplete.addOnce(function() {thisObj._turn();}, this);

};
IvxTile.prototype.flipV = function () {
    var thisObj, parent, val;

    val = this.scale.y * -1;

    thisObj = this;
    parent = this.parent
    parent.eventActive(false);
    parent.tween =this.game.add.tween(this.scale);
    parent.tween.to({y: val}, ivxCfg.tweenTIME , Phaser.Easing.Linear.None, true);
    parent.tween.onComplete.addOnce(function() {thisObj._turn();}, this);

};

IvxTile.prototype.shuffle = function () {
    var idx;

    idx = Math.floor(Math.random() * this.parent.cellArr.length);
    this.swapIdx(idx);

    this.scale.x *= Math.floor(Math.random()  * 2)||-1;
    this.scale.y *= Math.floor(Math.random()  * 2)||-1;

    this.angle  = (Math.floor(Math.random() * 4) * 90);
    this.checkCorrect();
};
var IvxTileGroup = Ivx.extend(Phaser.Group,'PGroup', function(game) {
    Phaser.Group.call(this, game);
    var activeTile = null;
    var thisObj = this;

    Object.defineProperty(this, "active", {
        set: function(tile) {
            var prior;

            prior = activeTile;
            activeTile = tile;

            prior && prior.adjustTint();

            activeTile &&  activeTile.adjustTint();

        },
        get: function() {
            return activeTile;
        }
    });
    this._shuffleDELAY = 3000;
    this.cellArr = [];
});
IvxTileGroup.prototype.eventCompleted = function() {
    console.log('IvxTileGroup.eventCompleted: **todo: override **');
};
IvxTileGroup.prototype.eventActive = function(active) {
    console.log('IvxTileGroup.eventActive: **todo: override **');
};
IvxTileGroup.prototype.select = function(tile, eventDragStart) {
      var current;
      current = this.active;

      if (this.active) {
          this.active = null;
      }
      if (current !== tile) {
          this.active = tile;
      }
};
IvxTileGroup.prototype.prep = function(bg) {
    var game, thisObj, sample, bmd, url, cols, rows,
        size, sizex, sizey,
        count, scale, offx, offy,  mag, h, scale2;

    thisObj = this;
    game = this.game;

    cols = 4;

    sample = game.add.sprite(0,0, 'puzzle');
    sample.visible = false;

    sample.aspectRatio = sample.width / sample.height;

    /*
    if (sample.aspectRatio > game.scale.aspectRatio) {
        scale = game.width / sample.width;
        size = (game.width / cols)|0;
        rows =  (0.5 + ((sample.height * scale)/size))|0;
    } else {
        scale = game.height / sample.height;
        //todo:
        rows = cols;
        size = (game.height / rows)|0;
        //cols =  (0.5 + ((sample.width * scale)/size))|0;
        cols =  (0 + ((sample.width * scale)/size))|0;
    }
    */

    if (sample.aspectRatio > game.scale.aspectRatio) {
        scale = game.width / sample.width;
    } else {
        scale = game.height / sample.height;
    }
    if (game.scale.aspectRatio < 1 ) {
        size = (game.width / cols)|0;
        rows =  (((sample.height * scale)/size))|0;
        scale2 = ((100 *(rows * size) / game.height)|0) / 100;
    } else {
        rows = cols;
        size = (game.height / rows)|0;
        cols =  (((sample.height * scale)/size))|0;
        scale2 = 1;
    }

    console.log('prep: sample.width: ' + sample.width + ' height: ' + sample.height);

    mag = sample.scale.getMagnitude();
    sample.mag = mag;
    sample.scale.setMagnitude(scale2 * mag * scale);

    count = cols * rows;

    console.log('prep: bmd: size:'+size + ' cols:' +cols+' rows: '+rows);
    bmd = game.add.bitmapData(size * cols, size * rows);

    this.offx =  (bg.bmd.width  - bmd.width)/2|0;
    this.offy = (bg.bmd.height  - bmd.height)/2|0;

    var rect   = {x: this.offx, y: this.offy, width: bmd.width, height: bmd.height};
    bmd.copyRect(bg.bmd, rect, 0, 0);

    offx = (bmd.width  - sample.width)/2|0;
    offy = (bmd.height  - sample.height)/2|0;
    sample.x = offx;
    sample.y = offy;
    bmd.draw(sample, offx, offy);
   //url = bmd.canvas.toDataURL();

    this.board = {
        url: url,
        sample: sample,
        bg: bg,
        bmd: bmd,
        cols: cols,
        rows: rows,
        count: count,
        size: size,
        scale: scale,
        offx: this.offx,
        offy: this.offy,
    };

    ivxCfg.board = this.board;

    game.cache.addSpriteSheet('pscaled', null, bmd.canvas, size, size, count, 0, 0);

    this.breed();
    this.shuffle();
};
IvxTileGroup.prototype.breed = function(cols) {
    var i;
    console.log('IvxTileGroup.breed:');
    for(i=0; i < this.board.count; i++) {
        new IvxTile(this);
    }

    return;
};
IvxTileGroup.prototype._shuffle = function() {
    var len = this.cellArr.length;
    for(var i=0; i < len; i++) {
        this.cellArr[i].shuffle();
        this.cellArr[i].visible = true;
    }
};
IvxTileGroup.prototype.shuffle = function() {
    var thisObj = this;

    this._shuffleTO = window.setTimeout(function() {
            thisObj._shuffle();
        },
        thisObj._shuffleDELAY
    );
};
IvxTileGroup.prototype.checkComplete = function() {
    var len, tile;
    len = this.cellArr.length;
    for (var i = 0; i < len; i++) {
        if (!this.cellArr[i].isCorrect()) {
            return false;
        }
    }
    this.eventActive(null);
    console.log('IvxTileGroup.checkComplete: true');
    this.eventCompleted();
    return true;
};
<commit_msg>fix Complete on click during preview<commit_after>
var IvxBtn = Ivx.extend(Phaser.Button,'PSprite', function(group, idx, onclick) {
    var game, x, y, thisObj, bgIdx, activeIdx, spriteIdx, scale, mag;
    x = 20+ (120 * idx);
    game = group.game;

    bgIdx = 0;
    activeIdx = 1;
    spriteIdx = idx + 2;

    thisObj = this;
    Phaser.Button.call(this, group.game, x, y, 'ui', function() {
        onclick();
    },
    bgIdx, bgIdx, bgIdx);
    group.add(this);

    this.onInputDown.add(function() {
       thisObj.eventInputDown(idx);
    });
    this.onInputUp.add(function() {
        thisObj.eventInputUp(idx);
    });

    this.active = new Phaser.Sprite(game, 0, 0, 'ui', activeIdx);
    this.icon = new Phaser.Sprite(game, 0, 0, 'ui', spriteIdx);
    this.addChild(this.active);
    this.addChild(this.icon);
    this.active.visible = false;

});
IvxBtn.prototype.eventClicked = function(idx) {
    //console.log('eventClicked: ' + idx);
};
IvxBtn.prototype.eventInputDown = function(idx) {
    //console.log('eventInputDown: ' + idx);
    this.active.visible = true;
};
IvxBtn.prototype.eventInputUp = function(idx) {
    //console.log('eventInputUp: ' + idx);
    this.active.visible = false;
};

var IvxTile = Ivx.extend(Phaser.Sprite,'PSprite', function(group) {
    var thisObj, board, col, row, x, y, midpoint, mag, rect;

    board = group.board;

    this.idx = group.cellArr.length;

    col = this.idx % board.cols;
    row = (this.idx / board.cols)|0;

    x = col * (board.size);
    y = row * (board.size);
    //console.log('IvxTile: idx: ' + this.idx + ' col: ' + col + ' row: ' + row + ' x: ' + x + ' y:'+y);

    Phaser.Sprite.call(this, group.game, x, y, 'pscaled', this.idx);

    midpoint = (board.size)/2|0;

    this.x = board.offx + ((midpoint + col * board.size ) );
    this.y = board.offy + ((midpoint + row * board.size ) );

    this.anchor.setTo(0.5);

    this.inputEnabled = true;
   // this.input.enableDrag();

    thisObj = this;
    this.events.onDragStart.add(function(sprite, pointer) {

        thisObj.eventDragStart(sprite, pointer);
    });
    this.events.onDragStop.add(function(sprite, pointer) {
        thisObj.eventDragStop(sprite, pointer);
    });

    group.add(this);
    group.cellArr.push(this);

    //this.visible  = false;

    this.orig = {
        mag: mag,
        txt: this.texture,
        angle: this.angle,
        scalex: this.scale.x,
        scaley: this.scale.y,
        x: this.x,
        y: this.y,
        tint: this.tint
    };

});
IvxTile.prototype.isCorrect = function () {
    var o, correct;
    o = this.orig;

    if(this.parent._preview) {
        return false;
    }

    if (this.scale.x < 0 && this.scale.y < 0) {
        this.scale.x *= -1;
        this.scale.y *= -1;
        this.angle += 180;
    }

    correct =  (!this.angle) && (this.x === o.x) && (this.y === o.y) &&  (this.texture === o.txt);
    correct = correct && (this.scale.x === o.scalex) && (this.scale.y === o.scaley)

    return correct;
};

IvxTile.prototype.isActive = function () {
    return this === this.parent.active;
};
IvxTile.prototype.adjustTint = function () {
    if (this.isCorrect()) {
       this.tint = this.orig.tint && 0xffffff;
    } else {
       if (this.isActive()) {
            this.tint = this.orig.tint && 0x55ff55;
       } else {
           this.tint = this.orig.tint && 0xff8888;
       }
    }
};

IvxTile.prototype.checkCorrect = function (animate) {
    var correct;

    correct = this.isCorrect();
    if (correct) {
       this.inputEnabled = false;
       if (this.isActive()) {
        this.parent.active = null;
        this.parent.eventActive(false);
       }
    }
    this.adjustTint();
    return correct;
};

IvxTile.prototype.swap = function (tile) {

    var swap;
    swap =  { txt: tile.texture,  angle: tile.angle, scalex: tile.scale.x, scaley: tile.scale.y };

    tile.texture = this.texture;
    tile.angle = this.angle;
    tile.scale.x = this.scale.x;
    tile.scale.y = this.scale.y;

    this.texture = swap.txt;
    this.angle = swap.angle;
    this.scale.x = swap.scalex;
    this.scale.y = swap.scaley;

};
IvxTile.prototype.tileIdx = function (idx) {
    return this.parent.cellArr[idx];
};
IvxTile.prototype.swapIdx = function (idx) {
    var tile;
    tile = this.parent.cellArr[idx];
    this.swap(tile);
    return tile;
};
IvxTile.prototype.calcIdx = function() {
    var col, row, idx, tile, board, size;

    size = Math.abs(this.width);
    board = this.parent.board;

    col = ((this.x - board.offx ) / size)|0;
    row = ((this.y - board.offy ) / size)|0;
    if ( (col+1) > board.cols || (row+1) > board.rows || col < 0 || row < 0) {
        return this.idx;
    }

    idx = col + row * board.cols;

    if (idx < this.parent.cellArr.length) {
        tile = this.tileIdx(idx);
        if (tile.isCorrect()) {
            return this.idx;
        }
        return idx;
    }
    return this.idx;
};
IvxTile.prototype.eventDragStart = function (sprite, pointer) {

    if(this.parent._preview) {
        return false;
    }

    this.origActive =  this.parent.active;
    this.parent.eventActive(false);

    this.parent.active = this;

    this.last = { x: this.x, y: this.y, type: this.position.type};
    this.bringToTop();
};
IvxTile.prototype.eventDragStop = function (sprite, pointer) {

    var idx, tile;
    if(this.parent._preview) {
        return false;
    }

    idx = this.calcIdx();

    tile = this.swapIdx(idx);
    this.x = this.last.x;
    this.y = this.last.y;
    if (this !== tile) {
        this.parent.active = tile;
        this.checkCorrect();
    } else {
        if (this.origActive === this) {
            this.parent.active = null;
        }
    }
    this.parent.eventActive(this.parent.active);

    tile.checkCorrect(true) && this.parent.checkComplete();

};
IvxTile.prototype._turn = function () {

    this.parent.tween = null;
    this.parent.eventActive(true);
    this.checkCorrect(true) && this.parent.checkComplete();

};
IvxTile.prototype.turnRight = function () {
    var thisObj, angle, parent;

    thisObj = this;
    angle = this.angle + 90;

    parent = this.parent
    parent.eventActive(false);
    parent.tween =this.game.add.tween(this);
    parent.tween.to({angle: angle}, ivxCfg.tweenTIME , Phaser.Easing.Linear.None, true);
    parent.tween.onComplete.addOnce(function() {thisObj._turn();}, this);
};
IvxTile.prototype.turnLeft = function () {
    var thisObj, angle, parent;

    thisObj = this;
    angle = this.angle - 90;

    parent = this.parent
    parent.eventActive(false);
    parent.tween =this.game.add.tween(this);
    parent.tween.to({angle: angle}, ivxCfg.tweenTIME , Phaser.Easing.Linear.None, true);
    parent.tween.onComplete.addOnce(function() {thisObj._turn();}, this);

};
IvxTile.prototype.flipH = function () {
    var thisObj, parent, val;

    val = this.scale.x * -1;

    thisObj = this;
    parent = this.parent
    parent.eventActive(false);
    parent.tween =this.game.add.tween(this.scale);
    parent.tween.to({x: val}, ivxCfg.tweenTIME , Phaser.Easing.Linear.None, true);
    parent.tween.onComplete.addOnce(function() {thisObj._turn();}, this);

};
IvxTile.prototype.flipV = function () {
    var thisObj, parent, val;

    val = this.scale.y * -1;

    thisObj = this;
    parent = this.parent
    parent.eventActive(false);
    parent.tween =this.game.add.tween(this.scale);
    parent.tween.to({y: val}, ivxCfg.tweenTIME , Phaser.Easing.Linear.None, true);
    parent.tween.onComplete.addOnce(function() {thisObj._turn();}, this);

};

IvxTile.prototype.shuffle = function () {
    var idx;

    idx = Math.floor(Math.random() * this.parent.cellArr.length);
    this.swapIdx(idx);

    this.scale.x *= Math.floor(Math.random()  * 2)||-1;
    this.scale.y *= Math.floor(Math.random()  * 2)||-1;

    this.angle  = (Math.floor(Math.random() * 4) * 90);
    this.input.enableDrag();
    this.checkCorrect();
};
var IvxTileGroup = Ivx.extend(Phaser.Group,'PGroup', function(game) {
    Phaser.Group.call(this, game);
    var activeTile = null;
    var thisObj = this;

    Object.defineProperty(this, "active", {
        set: function(tile) {
            var prior;

            prior = activeTile;
            activeTile = tile;

            prior && prior.adjustTint();

            activeTile &&  activeTile.adjustTint();

        },
        get: function() {
            return activeTile;
        }
    });
    this._shuffleDELAY = 3000;
    this.cellArr = [];
    this._preview = true;
});
IvxTileGroup.prototype.eventCompleted = function() {
    console.log('IvxTileGroup.eventCompleted: **todo: override **');
};
IvxTileGroup.prototype.eventActive = function(active) {
    console.log('IvxTileGroup.eventActive: **todo: override **');
};
IvxTileGroup.prototype.select = function(tile, eventDragStart) {
      var current;
      current = this.active;

      if (this.active) {
          this.active = null;
      }
      if (current !== tile) {
          this.active = tile;
      }
};
IvxTileGroup.prototype.prep = function(bg) {
    var game, thisObj, sample, bmd, url, cols, rows,
        size, sizex, sizey,
        count, scale, offx, offy,  mag, h, scale2;

    thisObj = this;
    game = this.game;

    cols = 4;

    sample = game.add.sprite(0,0, 'puzzle');
    sample.visible = false;

    sample.aspectRatio = sample.width / sample.height;

    /*
    if (sample.aspectRatio > game.scale.aspectRatio) {
        scale = game.width / sample.width;
        size = (game.width / cols)|0;
        rows =  (0.5 + ((sample.height * scale)/size))|0;
    } else {
        scale = game.height / sample.height;
        //todo:
        rows = cols;
        size = (game.height / rows)|0;
        //cols =  (0.5 + ((sample.width * scale)/size))|0;
        cols =  (0 + ((sample.width * scale)/size))|0;
    }
    */

    if (sample.aspectRatio > game.scale.aspectRatio) {
        scale = game.width / sample.width;
    } else {
        scale = game.height / sample.height;
    }
    if (game.scale.aspectRatio < 1 ) {
        size = (game.width / cols)|0;
        rows =  (((sample.height * scale)/size))|0;
        scale2 = ((100 *(rows * size) / game.height)|0) / 100;
    } else {
        rows = cols;
        size = (game.height / rows)|0;
        cols =  (((sample.height * scale)/size))|0;
        scale2 = 1;
    }

    console.log('prep: sample.width: ' + sample.width + ' height: ' + sample.height);

    mag = sample.scale.getMagnitude();
    sample.mag = mag;
    sample.scale.setMagnitude(scale2 * mag * scale);

    count = cols * rows;

    console.log('prep: bmd: size:'+size + ' cols:' +cols+' rows: '+rows);
    bmd = game.add.bitmapData(size * cols, size * rows);

    this.offx =  (bg.bmd.width  - bmd.width)/2|0;
    this.offy = (bg.bmd.height  - bmd.height)/2|0;

    var rect   = {x: this.offx, y: this.offy, width: bmd.width, height: bmd.height};
    bmd.copyRect(bg.bmd, rect, 0, 0);

    offx = (bmd.width  - sample.width)/2|0;
    offy = (bmd.height  - sample.height)/2|0;
    sample.x = offx;
    sample.y = offy;
    bmd.draw(sample, offx, offy);
   //url = bmd.canvas.toDataURL();

    this.board = {
        url: url,
        sample: sample,
        bg: bg,
        bmd: bmd,
        cols: cols,
        rows: rows,
        count: count,
        size: size,
        scale: scale,
        offx: this.offx,
        offy: this.offy,
    };

    ivxCfg.board = this.board;

    game.cache.addSpriteSheet('pscaled', null, bmd.canvas, size, size, count, 0, 0);

    this.breed();
    this.shuffle();
};
IvxTileGroup.prototype.breed = function(cols) {
    var i;
    this._preview = true;
    console.log('IvxTileGroup.breed:');
    for(i=0; i < this.board.count; i++) {
        new IvxTile(this);
    }

    return;
};
IvxTileGroup.prototype._shuffle = function() {
    var len = this.cellArr.length;
    for(var i=0; i < len; i++) {
        this.cellArr[i].shuffle();
        this.cellArr[i].visible = true;
    }
    this._preview = false;
};
IvxTileGroup.prototype.shuffle = function() {
    var thisObj = this;

    this._shuffleTO = window.setTimeout(function() {
            thisObj._shuffle();
        },
        thisObj._shuffleDELAY
    );
};
IvxTileGroup.prototype.checkComplete = function() {
    var len, tile;
    len = this.cellArr.length;
    for (var i = 0; i < len; i++) {
        if (!this.cellArr[i].isCorrect()) {
            return false;
        }
    }
    this.eventActive(null);
    console.log('IvxTileGroup.checkComplete: true');
    this.eventCompleted();
    return true;
};
<|endoftext|>


<commit_before>module.exports = {
  APIS: [

  ],
  COMPONENTS: [
    {
      title: 'Button', // 必须
      description: 'Button Example',
      icon: 'https://os.alipayobjects.com/rmsportal/lOXYjfSRPpkwudh.png',
      module: require('../components/button/demo/basic'), // 必须
    },
    {
      title: 'Card', // 必须
      description: 'Card Example',
      icon: 'https://os.alipayobjects.com/rmsportal/lOXYjfSRPpkwudh.png',
      module: require('../components/card/demo/basic'), // 必须
    },
    {
      title: 'Flex', // 必须
      description: 'Flex Example',
      icon: 'https://os.alipayobjects.com/rmsportal/KZtGFWmnMUFpiSE.png',
      module: require('../components/flex/demo/basic'), // 必须
    },
    {
      title: 'List', // 必须
      description: 'List Example',
      icon: 'https://os.alipayobjects.com/rmsportal/wlNeoTpEKIpTcOW.png',
      module: require('../components/list/demo/basic'), // 必须
    },
    {
      title: 'Modal', // 必须
      description: 'Modal Example',
      icon: 'https://os.alipayobjects.com/rmsportal/AMszKQQdMvMmYng.png',
      module: require('../components/modal/demo/basic'), // 必须
    },
    {
      title: 'Tag', // 必须
      description: 'Tag Example',
      icon: 'https://os.alipayobjects.com/rmsportal/AkXOzPmaytaVYLD.png',
      module: require('../components/tag/demo/basic'), // 必须
    },
    {
      title: 'TopNotice', // 必须
      description: 'TopNotice Example',
      icon: 'https://os.alipayobjects.com/rmsportal/AraRKTSdXQbKkGv.png',
      module: require('../components/top-notice/demo/basic'), // 必须
    },
    {
      title: 'WingBlank', // 必须
      description: 'WingBlank Example',
      icon: 'https://os.alipayobjects.com/rmsportal/WzZoGzTRKzQgMWi.png',
      module: require('../components/wing-blank/demo/basic'), // 必须
    },
    {
      title: 'WhiteSpace', // 必须
      description: 'WhiteSpace Example',
      icon: 'https://os.alipayobjects.com/rmsportal/mioJMWDMAmiurTR.png',
      module: require('../components/white-space/demo/basic'), // 必须
    },
    {
      title: 'Picker', // 必须
      description: 'Picker Example',
      icon: 'https://os.alipayobjects.com/rmsportal/mioJMWDMAmiurTR.png',
      module: require('../components/picker/demo/popup'), // 必须
    },
    {
      title: 'DatePicker', // 必须
      description: 'DatePicker Example',
      icon: 'https://os.alipayobjects.com/rmsportal/mioJMWDMAmiurTR.png',
      module: require('../components/date-picker/demo/popup'), // 必须
    },
  ],
};
<commit_msg>改变 demo 顺序<commit_after>module.exports = {
  APIS: [

  ],
  COMPONENTS: [
    {
      title: 'Button', // 必须
      description: 'Button Example',
      icon: 'https://os.alipayobjects.com/rmsportal/lOXYjfSRPpkwudh.png',
      module: require('../components/button/demo/basic'), // 必须
    },
    {
      title: 'Card', // 必须
      description: 'Card Example',
      icon: 'https://os.alipayobjects.com/rmsportal/lOXYjfSRPpkwudh.png',
      module: require('../components/card/demo/basic'), // 必须
    },
    {
      title: 'DatePicker', // 必须
      description: 'DatePicker Example',
      icon: 'https://os.alipayobjects.com/rmsportal/mioJMWDMAmiurTR.png',
      module: require('../components/date-picker/demo/popup'), // 必须
    },
    {
      title: 'Flex', // 必须
      description: 'Flex Example',
      icon: 'https://os.alipayobjects.com/rmsportal/KZtGFWmnMUFpiSE.png',
      module: require('../components/flex/demo/basic'), // 必须
    },
    {
      title: 'List', // 必须
      description: 'List Example',
      icon: 'https://os.alipayobjects.com/rmsportal/wlNeoTpEKIpTcOW.png',
      module: require('../components/list/demo/basic'), // 必须
    },
    {
      title: 'Modal', // 必须
      description: 'Modal Example',
      icon: 'https://os.alipayobjects.com/rmsportal/AMszKQQdMvMmYng.png',
      module: require('../components/modal/demo/basic'), // 必须
    },
    {
      title: 'Picker', // 必须
      description: 'Picker Example',
      icon: 'https://os.alipayobjects.com/rmsportal/mioJMWDMAmiurTR.png',
      module: require('../components/picker/demo/popup'), // 必须
    },
    {
      title: 'Tag', // 必须
      description: 'Tag Example',
      icon: 'https://os.alipayobjects.com/rmsportal/AkXOzPmaytaVYLD.png',
      module: require('../components/tag/demo/basic'), // 必须
    },
    {
      title: 'TopNotice', // 必须
      description: 'TopNotice Example',
      icon: 'https://os.alipayobjects.com/rmsportal/AraRKTSdXQbKkGv.png',
      module: require('../components/top-notice/demo/basic'), // 必须
    },
    {
      title: 'WingBlank', // 必须
      description: 'WingBlank Example',
      icon: 'https://os.alipayobjects.com/rmsportal/WzZoGzTRKzQgMWi.png',
      module: require('../components/wing-blank/demo/basic'), // 必须
    },
    {
      title: 'WhiteSpace', // 必须
      description: 'WhiteSpace Example',
      icon: 'https://os.alipayobjects.com/rmsportal/mioJMWDMAmiurTR.png',
      module: require('../components/white-space/demo/basic'), // 必须
    },
  ],
};
<|endoftext|>


<commit_before>var pg = require('pg');
var _ = require('underscore');
var request = require('request');
var jwt = require('jsonwebtoken');
var secret = require('../../config/secret');
var db_settings = require('../../server.js').db_settings;
var errors = require('../../config/errors');

var Ajv = require('ajv');
var schema = require('../../models/query');
var ajv = Ajv({"format": "full"});
var validate = ajv.compile(schema);

var CouchDB_Client = require('../connectors/CouchDB_Client.js');
var EnviroCar_Client = require('../connectors/EnviroCar_Client.js');
var Postgres_Client = require('../connectors/Postgres_Client.js');
var Parliament_Client = require('../connectors/Parliament_Client.js');

// POST
exports.request = function(req, res){

    // Create timestamp
    var time = Date.now();
    // Check if Header contains Access-Token
    var accessToken = "";
    Flag = true;
    if(!req.query.authorization || req.query.authorization === "") {
        if(!req.headers.authorization || req.headers.authorization === ""){
            console.log("error. no valid authorization");
            Flag = false;
        } else {
            accessToken = req.headers.authorization;
            Flag = true;
        }
    } else {
        accessToken = req.query.authorization;
        Flag = true;
    }
    if(!Flag){
       res.status(errors.authentication.error_2.code).send(errors.authentication.error_2);
       return console.error(errors.authentication.error_2.message);
    } else {
        var url = "postgres://" + db_settings.user + ":" + db_settings.password + "@" + db_settings.host + ":" + db_settings.port + "/" + db_settings.database_name;

        // Connect to Database
        pg.connect(url, function(err, client, done) {
            if (err) {
                res.status(errors.database.error_1.code).send(errors.database.error_1);
                return console.error(errors.database.error_1.message, err);
            } else {

                // Database Query
                client.query('SELECT * FROM Apps WHERE app_hash=$1;', [
                    accessToken
                ], function(err, result) {
                    done();

                    if (err) {
                        res.status(errors.database.error_2.code).send(_.extend(errors.database.error_2, err));
                        return console.error(errors.database.error_2.message, err);
                    } else {

                        // Check if App exists
                        if (result.rows.length === 0) {
                            res.status(errors.query.error_1.code).send(errors.query.error_1);
                            console.error(errors.query.error_1.message);
                        } else {
                            query = 'SELECT queries.query_id, queries.query_extern, queries.query_intern, queries.query_description, categories.category_name, endpoints.endpoint_host, endpoints.endpoint_port, endpoints.endpoint_path, datastores.ds_type, datastores.ds_host, datastores.ds_port, datastores.db_instance '
                            query += 'FROM main_datasets INNER JOIN sub_datasets ON main_datasets.md_id = sub_datasets.md_id INNER JOIN queries ON sub_datasets.sd_id = queries.sd_id INNER JOIN endpoints ON main_datasets.endpoint_id = endpoints.endpoint_id INNER JOIN datastores ON main_datasets.ds_id = datastores.ds_id INNER JOIN admins ON main_datasets.created_by = admins.username INNER JOIN categories_relationships On categories_relationships.md_id = main_datasets.md_id INNER JOIN categories ON categories_relationships.category_id = categories.category_id '

                            words = req.params.category_name.split("&");
                            var index = 1;
                            var params = [];
                            for(i in words) {
                                word = words[i].split(",");
                                if(i==0) {
                                    for(j in word) {
                                        console.log(word[j]);
                                        if(j==0) {
                                            tmp = "WHERE categories.category_name LIKE '%' || $"+index+" || '%' ";
                                            query += tmp;
                                            params.push(word[j]);
                                            index++;
                                            logCategory(client, word[j], accessToken);
                                        } else {
                                            tmp = "OR categories.category_name LIKE '%' || $"+index+" || '%' ";
                                            query += tmp;
                                            params.push(word[j]);
                                            index++;
                                            logCategory(client, word[j], accessToken);
                                        }
                                    }
                                } else {
                                    for(j in word) {
                                        if(j==0) {
                                            tmp = "AND categories.category_name LIKE '%' || $"+index+" || '%' ";
                                            query += tmp;
                                            params.push(word[j]);
                                            index++;
                                            logCategory(client, word[j], accessToken);
                                        } else {
                                            tmp = "OR categories.category_name LIKE '%' || $"+index+" || '%' ";
                                            query += tmp;
                                            params.push(word[j]);
                                            index++;
                                            logCategory(client, word[j], accessToken);
                                        }
                                    }
                                }
                            }
                            query += "AND queries.active='true';";
                            console.log(query);
                            client.query(query, params, function(err, result) {
                                if(err) {
                                    console.log(err);
                                } else {
                                    if(result.rows.length === 0) {
                                        console.log("No entry for this category");
                                        res.status(errors.query.error_3.code).send(errors.query.error_3);
                                    } else {
                                        //res.status(201).send(result.rows);
                                        var answerCount = 0;
                                        for(index in result.rows) {
                                            // Prepare Connectors
                                            var Answer = {
                                                search_tag: req.params,
                                                results: [],
                                                data: {
                                                    Rest: {
                                                        time: 0,
                                                        count: 0,
                                                        data: []
                                                    },
                                                    postgres: {
                                                        time: 0,
                                                        count: 0,
                                                        data: []
                                                    },
                                                    parliament: {
                                                        time: 0,
                                                        count: 0,
                                                        data: []
                                                    },
                                                    couchDB: {
                                                        time: 0,
                                                        count: 0,
                                                        data: []
                                                    },
                                                    Parliament: {
                                                        time: 0,
                                                        count: 0,
                                                        data: []
                                                    }
                                                }
                                            }
                                            switch(result.rows[index].ds_type) {
                                                /** TODO:
                                                 * Need to get query from database, then execute
                                                 */
                                                case("POSTGRESQL"):
                                                    answerCount ++;
                                                    // PostgreSQL
                                                    _url = "postgres://" + result.rows[index].db_user + ":" + result.rows[index].db_password + "@" + result.rows[index].db_host + ":" + result.rows[index].db_port + "/" + result.rows[index].db_instance;
                                                    var postgres_Client = new Postgres_Client(url);
                                                    postgres_Client.setURL(url);
                                                    /*postgres_Client.query(result.rows[index].query_intern, [], function(_result, err) {
                                                        if(err) {
                                                            //console.log(err);
                                                            finish(res, Answers, answerCount, result.rows.length);
                                                        } else {
                                                            Result = {
                                                                preview: _result.parseRowsByColNames("Datasets").Datasets,
                                                                query: result.rows[index].query_intern,
                                                                query_description: result.rows[index].query_description,
                                                                sd_name: result.rows[index].sd_name,
                                                                sd_description: result.rows[index].sd_description,
                                                                md_name: result.rows[index].md_name,
                                                                md_description: result.rows[index].md_description
                                                            }
                                                            Answer.data.postgres.push(Result);
                                                            finish(res, Answer, answerCount, result.rows.length);
                                                        }
                                                    });*/
                                                    finish(res, Answer, answerCount, result.rows.length);
                                                    break;
                                                case("REST"):
                                                    var name = result.rows[index].sd_name;
                                                    var description = result.rows[index].sd_description;
                                                    console.log(result.rows[index]);
                                                    _url = result.rows[index].ds_host;
                                                    if(result.rows[index].ds_port != null && result.rows[index].ds_port != "") {
                                                        console.log(ds_port);
                                                        _url += ":" + result.rows[index].ds_port + "/";
                                                    }
                                                    _url += result.rows[index].query_intern;
                                                    request(_url, function(error, response, body) {
                                                        if(!error) {
                                                            dt = {
                                                                name: name,
                                                                descritpion: description,
                                                                preview: JSON.parse(body)
                                                            }
                                                            Answer.data.Rest.data.push(dt);
                                                            Answer.data.Rest.count ++;
                                                            Answer.data.Rest.time = (Date.now()-time) / 1000 + " s";
                                                            answerCount ++;
                                                            finish(res, Answer, answerCount, result.rows.length);
                                                        } else {
                                                            console.log(error);
                                                            console.log(response);
                                                            answerCount ++;
                                                            finish(res, Answer, answerCount, result.rows.length);
                                                        }
                                                    });
                                                    break;
                                                case("COUCHDB"):
                                                    var length = result.rows.length;
                                                    var name = result.rows[index].sd_name;
                                                    var description = result.rows[index].sd_description;

                                                    var couchdb_Client = new CouchDB_Client(result.rows[index].ds_host, result.rows[index].ds_port);
                                                    couchdb_Client.useDatabase(result.rows[index].db_instance);
                                                    couchdb_Client.query(result.rows[index].query_intern, function (error, result) {
                                                        if(error) {
                                                            console.log(error);
                                                        } else {
                                                            dt = {
                                                                name: name,
                                                                description: description,
                                                                preview: result
                                                            }
                                                            Answer.data.couchDB.data.push(dt);
                                                            Answer.data.couchDB.count ++;
                                                            Answer.data.couchDB.time = (Date.now()-time) / 1000 + " s";
                                                        }
                                                        answerCount ++;
                                                        finish(res, Answer, answerCount, length);
                                                    });
                                                    break;
                                                case("PARLIAMENT"):
                                                    var length = result.rows.length;
                                                    parliament_Client = new Parliament_Client(result.rows[index].ds_host, result.rows[index].ds_port);
                                                    parliament_Client.query(result.rows[index].query_intern, function (error, result) {
                                                        if(error) {
                                                            console.log(error);
                                                            answerCount ++;
                                                            finish(res, Answer, answerCount, length)
                                                        } else {
                                                            Answer.data.Parliament.data.push(result);
                                                            Answer.data.Parliament.count ++;
                                                            Answer.data.Parliament.time = (Date.now()-time) / 1000 + " s";
                                                            answerCount ++;
                                                            finish(res, Answer, answerCount, length)
                                                        }
                                                    });
                                                    break;
                                                default:
                                                    answerCount++;
                                                    console.log("unknown Database");
                                                    console.log(result.rows[index].ds_type);
                                                    finish(res, Answer, answerCount, result.rows.length);
                                                    break;
                                            }

                                        }
                                    }
                                }
                            });
                        }
                    }
                });
            }
        });
    }
};

/**
 * Check
 * @param  {number} count
 * @param  {number} maximum
 * @return {boolean} true or false
 */
var check = function (count, max) {
    if(count == max) {
        return true;
    } else {
        return false;
    }
};

/**
 * Finish
 */
var finish = function (res, Answer, answerCount, max) {
    console.log(answerCount);
    console.log(max)
    if(check(answerCount, max)) {
        res.status(201).send(Answer);
    }
};

var logCategory = function (client, category_name, accessToken) {
    client.query("SELECT category_id FROM categories WHERE category_name LIKE '%' || $1 || '%' ", [
        category_name
    ], function (err, result) {
        if(err) {
            console.log(err);
        } else {
            if(result.rows.length == 0) {
                console.log("No Category");
            } else {
                console.log(result.rows[0].category_id);
                category_id = result.rows[0].category_id;
                client.query("INSERT INTO Logs(app_hash, timestamp, category_id, sd_id) VALUES ($1, now(), $2, null)", [accessToken, category_id], function (err, result) {
                    if(err) {
                        console.log(err);
                    } else {
                        //Logged the search
                    }
                });
            }
        }
    });
}
<commit_msg>Category Search fix<commit_after>var errors = require('./../../config/errors');
var client = require('./../db.js');
var _ = require('underscore');

var request = require('request');
var jwt = require('jsonwebtoken');
var secret = require('../../config/secret');

var Ajv = require('ajv');
var schema = require('../../models/query');
var ajv = Ajv({"format": "full"});
var validate = ajv.compile(schema);

var CouchDB_Client = require('../connectors/CouchDB_Client.js');
var EnviroCar_Client = require('../connectors/EnviroCar_Client.js');
var Postgres_Client = require('../connectors/Postgres_Client.js');
var Parliament_Client = require('../connectors/Parliament_Client.js');

// POST
exports.request = function(req, res){

    // Create timestamp
    var time = Date.now();
    // Check if Header contains Access-Token
    var accessToken = "";
    Flag = true;
    if(!req.query.authorization || req.query.authorization === "") {
        if(!req.headers.authorization || req.headers.authorization === ""){
            console.log("error. no valid authorization");
            Flag = false;
        } else {
            accessToken = req.headers.authorization;
            Flag = true;
        }
    } else {
        accessToken = req.query.authorization;
        Flag = true;
    }
    if(!Flag){
       res.status(errors.authentication.error_2.code).send(errors.authentication.error_2);
       return console.error(errors.authentication.error_2.message);
    } else {
        // Database Query
        client.query('SELECT * FROM Apps WHERE app_hash=$1;', [
            accessToken
        ], function(err, result) {
            if (err) {
                res.status(errors.database.error_2.code).send(_.extend(errors.database.error_2, err));
                return console.error(errors.database.error_2.message, err);
            } else {

                // Check if App exists
                if (result.length === 0) {
                    res.status(errors.query.error_1.code).send(errors.query.error_1);
                    console.error(errors.query.error_1.message);
                } else {
                    query = 'SELECT queries.query_id, queries.query_extern, queries.query_intern, queries.query_description, categories.category_name, endpoints.endpoint_host, endpoints.endpoint_port, endpoints.endpoint_path, datastores.ds_type, datastores.ds_host, datastores.ds_port, datastores.db_instance '
                    query += 'FROM main_datasets INNER JOIN sub_datasets ON main_datasets.md_id = sub_datasets.md_id INNER JOIN queries ON sub_datasets.sd_id = queries.sd_id INNER JOIN endpoints ON main_datasets.endpoint_id = endpoints.endpoint_id INNER JOIN datastores ON main_datasets.ds_id = datastores.ds_id INNER JOIN admins ON main_datasets.created_by = admins.username INNER JOIN categories_relationships On categories_relationships.md_id = main_datasets.md_id INNER JOIN categories ON categories_relationships.category_id = categories.category_id '

                    words = req.params.category_name.split("&");
                    var index = 1;
                    var params = [];
                    for(i in words) {
                        word = words[i].split(",");
                        if(i==0) {
                            for(j in word) {
                                console.log(word[j]);
                                if(j==0) {
                                    tmp = "WHERE categories.category_name LIKE '%' || $"+index+" || '%' ";
                                    query += tmp;
                                    params.push(word[j]);
                                    index++;
                                    logCategory(client, word[j], accessToken);
                                } else {
                                    tmp = "OR categories.category_name LIKE '%' || $"+index+" || '%' ";
                                    query += tmp;
                                    params.push(word[j]);
                                    index++;
                                    logCategory(client, word[j], accessToken);
                                }
                            }
                        } else {
                            for(j in word) {
                                if(j==0) {
                                    tmp = "AND categories.category_name LIKE '%' || $"+index+" || '%' ";
                                    query += tmp;
                                    params.push(word[j]);
                                    index++;
                                    logCategory(client, word[j], accessToken);
                                } else {
                                    tmp = "OR categories.category_name LIKE '%' || $"+index+" || '%' ";
                                    query += tmp;
                                    params.push(word[j]);
                                    index++;
                                    logCategory(client, word[j], accessToken);
                                }
                            }
                        }
                    }
                    query += "AND queries.active='true';";
                    console.log(query);
                    client.query(query, params, function(err, result) {
                        if(err) {
                            console.log(err);
                        } else {
                            if(result.length === 0) {
                                console.log("No entry for this category");
                                res.status(errors.query.error_3.code).send(errors.query.error_3);
                            } else {
                                //res.status(201).send(result);
                                var answerCount = 0;
                                for(index in result) {
                                    // Prepare Connectors
                                    var Answer = {
                                        search_tag: req.params,
                                        results: [],
                                        data: {
                                            Rest: {
                                                time: 0,
                                                count: 0,
                                                data: []
                                            },
                                            postgres: {
                                                time: 0,
                                                count: 0,
                                                data: []
                                            },
                                            parliament: {
                                                time: 0,
                                                count: 0,
                                                data: []
                                            },
                                            couchDB: {
                                                time: 0,
                                                count: 0,
                                                data: []
                                            },
                                            Parliament: {
                                                time: 0,
                                                count: 0,
                                                data: []
                                            }
                                        }
                                    }
                                    switch(result[index].ds_type) {
                                        /** TODO:
                                         * Need to get query from database, then execute
                                         */
                                        case("POSTGRESQL"):
                                            answerCount ++;
                                            // PostgreSQL
                                            _url = "postgres://" + result.rows[index].db_user + ":" + result.rows[index].db_password + "@" + result.rows[index].db_host + ":" + result.rows[index].db_port + "/" + result.rows[index].db_instance;
                                            var postgres_Client = new Postgres_Client(url);
                                            postgres_Client.setURL(url);
                                            /*postgres_Client.query(result[index].query_intern, [], function(_result, err) {
                                                if(err) {
                                                    //console.log(err);
                                                    finish(res, Answers, answerCount, result.length);
                                                } else {
                                                    Result = {
                                                        preview: _result.parseRowsByColNames("Datasets").Datasets,
                                                        query: result[index].query_intern,
                                                        query_description: result[index].query_description,
                                                        sd_name: result[index].sd_name,
                                                        sd_description: result[index].sd_description,
                                                        md_name: result[index].md_name,
                                                        md_description: result[index].md_description
                                                    }
                                                    Answer.data.postgres.push(Result);
                                                    finish(res, Answer, answerCount, result.length);
                                                }
                                            });*/
                                            finish(res, Answer, answerCount, result.length);
                                            break;
                                        case("REST"):
                                            var name = result[index].sd_name;
                                            var description = result[index].sd_description;
                                            console.log(result[index]);
                                            _url = result[index].ds_host;
                                            if(result[index].ds_port != null && result[index].ds_port != "") {
                                                console.log(ds_port);
                                                _url += ":" + result[index].ds_port + "/";
                                            }
                                            _url += result[index].query_intern;
                                            request(_url, function(error, response, body) {
                                                if(!error) {
                                                    dt = {
                                                        name: name,
                                                        descritpion: description,
                                                        preview: JSON.parse(body)
                                                    }
                                                    Answer.data.Rest.data.push(dt);
                                                    Answer.data.Rest.count ++;
                                                    Answer.data.Rest.time = (Date.now()-time) / 1000 + " s";
                                                    answerCount ++;
                                                    finish(res, Answer, answerCount, result.length);
                                                } else {
                                                    console.log(error);
                                                    console.log(response);
                                                    answerCount ++;
                                                    finish(res, Answer, answerCount, result.length);
                                                }
                                            });
                                            break;
                                        case("COUCHDB"):
                                            var length = result.length;
                                            var name = result[index].sd_name;
                                            var description = result[index].sd_description;

                                            var couchdb_Client = new CouchDB_Client(result[index].ds_host, result[index].ds_port);
                                            couchdb_Client.useDatabase(result[index].db_instance);
                                            couchdb_Client.query(result[index].query_intern, function (error, result) {
                                                if(error) {
                                                    console.log(error);
                                                } else {
                                                    dt = {
                                                        name: name,
                                                        description: description,
                                                        preview: result
                                                    }
                                                    Answer.data.couchDB.data.push(dt);
                                                    Answer.data.couchDB.count ++;
                                                    Answer.data.couchDB.time = (Date.now()-time) / 1000 + " s";
                                                }
                                                answerCount ++;
                                                finish(res, Answer, answerCount, length);
                                            });
                                            break;
                                        case("PARLIAMENT"):
                                            var length = result.length;
                                            parliament_Client = new Parliament_Client(result[index].ds_host, result[index].ds_port);
                                            parliament_Client.query(result[index].query_intern, function (error, result) {
                                                if(error) {
                                                    console.log(error);
                                                    answerCount ++;
                                                    finish(res, Answer, answerCount, length)
                                                } else {
                                                    Answer.data.Parliament.data.push(result);
                                                    Answer.data.Parliament.count ++;
                                                    Answer.data.Parliament.time = (Date.now()-time) / 1000 + " s";
                                                    answerCount ++;
                                                    finish(res, Answer, answerCount, length)
                                                }
                                            });
                                            break;
                                        default:
                                            answerCount++;
                                            console.log("unknown Database");
                                            console.log(result.rows[index].ds_type);
                                            finish(res, Answer, answerCount, result.length);
                                            break;
                                    }

                                }
                            }
                        }
                    });
                }
            }
        });
    }
};

/**
 * Check
 * @param  {number} count
 * @param  {number} maximum
 * @return {boolean} true or false
 */
var check = function (count, max) {
    if(count == max) {
        return true;
    } else {
        return false;
    }
};

/**
 * Finish
 */
var finish = function (res, Answer, answerCount, max) {
    console.log(answerCount);
    console.log(max)
    if(check(answerCount, max)) {
        res.status(201).send(Answer);
    }
};

var logCategory = function (client, category_name, accessToken) {
    client.query("SELECT category_id FROM categories WHERE category_name LIKE '%' || $1 || '%' ", [
        category_name
    ], function (err, result) {
        if(err) {
            console.log(err);
        } else {
            if(result.length == 0) {
                console.log("No Category");
            } else {
                console.log(result[0].category_id);
                category_id = result[0].category_id;
                client.query("INSERT INTO Logs(app_hash, timestamp, category_id, sd_id) VALUES ($1, now(), $2, null)", [accessToken, category_id], function (err, result) {
                    if(err) {
                        console.log(err);
                    } else {
                        //Logged the search
                    }
                });
            }
        }
    });
}
<|endoftext|>


<commit_before>/* Copyright (c) 2009, International Joint Commission
 *
 * This file is licensed under the ISCL. A copy of the license should be
 * distributed with the software; if not, you can obtain a copy here:
 * http://www.opensource.org/licenses/isc-license.txt
 */

/** @fileoverview
 * Abstract Syntax Tree
 *
 * Defines an Abstract Syntax Tree for an XPath expression, as well as a
 * ASTVisitor class (implements all node-specific visit methods) for
 * convenience, along with a Visitor "guide" that will take a simple visitor
 * class through all nodes.
 *
 * @author Tom Switzer (switzert@windsor.ijc.org)
 */
(function() {

var xpath = window.xpath = window.xpath || {};

xpath.util = {

    /**
     * Pretty simple function for "extending" an object with the properties of
     * another. It is a multi-argument function. The first argument is the
     * "base" object we wish to extend. The following arguments are objects
     * whose properties will be copied to the base object. If the base object
     * has a prop. of the same name, it will be overwritten. It is also extended
     * in order of the arguments, so if 2 objects whose properties we are
     * copying have props of the same name, the one that comes later in the
     * argument list will be used.
     *
     * @return The base object (ie. the first argument given)
     */
    extend: function(dest) {
        for (var i = 1; i < arguments.length; i++) {
            var src = arguments[i];
            for (var nm in src)
                dest[nm] = src[nm]
        }
        return dest;
    },

    /**
     * Fairly simple method that will return a new "class." This is based off of
     * Prototype's Class.create function, though simplified/dumbed down. So,
     * kudos to them. Head over to the
     * prototype web site to learn more. The function takes in an arbitrary
     * number of arguments. The arguments can either be existing classes (ie.
     * Functions) or objects. A class is then returned whose prototype instance
     * has the same properties as the arguments' prototype instance, in the case
     * of functions, or just the arguments' properties, in the case of objects.
     * A special method/property, {@code init}, will be used as the class
     * constructor.
     *
     * @note class is reserved for future use, so I use Class... don't like it
     */
    Class: function() {
        function Klass() {
            this.init.apply(this, arguments);
        }

        for (var i = 0; i < arguments.length; i++) {
            var a = arguments[i];
            xpath.util.extend(Klass.prototype,
                             typeof a == "function" ? a.prototype : a);
        }
        Klass.prototype.init = Klass.prototype.init || function() {};
        return (Klass.prototype.constructor = Klass);
    },

    /**
     * Searches for val in list and returns its index. If val cannot be found in
     * list, then this returns the index at which to insert val, while keeping
     * the list in sorted order. If l or r are given, then this operates on a
     * portion of the list, between [l,r). If cmp is give, then it will be used
     * to compare 2 elements. cmp should be a function that takes 2 arguments, a
     * and b, and returns < 0 if a  0 if a > b. If cmp is not
     * given, then the "natural" ordering (< and ==) is used instead. This is
     * guaranteed to run in O(log n) time, where n = r - l.
     *
     * @param list An array to search for val within
     * @param val The value to search for in the array
     * @param l The lower bound (inclusive) of the array to search in
     * @param r The upper bound (exclusive) of the array to search in
     * @param cmp A comparator to use to determine ordering
     * @return The index of val in the list (or where it should go)
     */
    binarySearch: function(list, val, l, r, cmp) {
        l = l || 0;
        r = (!r || r <= l) ? list.length : r;
        while (l < r) {
            c = Math.floor((l + r) / 2);
            if (list[c] == val)
                return c;
            if (cmp && cmp(list[c], val) < 0 || list[c] < val)
                l = c + 1;
            else
                r = c;
        }
        return l;
    },

    each: function(list, cb, data) {
        for (var i = 0, len = list.length; i < len; i++)
            if (cb.call(list[i], i, data) === false)
                return false;
        return true;
    },

    normalizeWhiteSpace: function(str) {
        return str.replace(/(^[\u0020\u0009\u000D\u000A]+|[\u0020\u0009\u000D\u000A]+$)/g, "")
                  .replace(/[\u0020\u0009\u000D\u000A]+/g, " ");
    }
};

})();
<commit_msg>Documented each and normalizeWhiteSpace utility functions.<commit_after>/* Copyright (c) 2009, International Joint Commission
 *
 * This file is licensed under the ISCL. A copy of the license should be
 * distributed with the software; if not, you can obtain a copy here:
 * http://www.opensource.org/licenses/isc-license.txt
 */

/** @fileoverview
 * Abstract Syntax Tree
 *
 * Defines an Abstract Syntax Tree for an XPath expression, as well as a
 * ASTVisitor class (implements all node-specific visit methods) for
 * convenience, along with a Visitor "guide" that will take a simple visitor
 * class through all nodes.
 *
 * @author Tom Switzer (switzert@windsor.ijc.org)
 */
(function() {

var xpath = window.xpath = window.xpath || {};

xpath.util = {

    /**
     * Pretty simple function for "extending" an object with the properties of
     * another. It is a multi-argument function. The first argument is the
     * "base" object we wish to extend. The following arguments are objects
     * whose properties will be copied to the base object. If the base object
     * has a prop. of the same name, it will be overwritten. It is also extended
     * in order of the arguments, so if 2 objects whose properties we are
     * copying have props of the same name, the one that comes later in the
     * argument list will be used.
     *
     * @return The base object (ie. the first argument given)
     */
    extend: function(dest) {
        for (var i = 1; i < arguments.length; i++) {
            var src = arguments[i];
            for (var nm in src)
                dest[nm] = src[nm]
        }
        return dest;
    },

    /**
     * Fairly simple method that will return a new "class." This is based off of
     * Prototype's Class.create function, though simplified/dumbed down. So,
     * kudos to them. Head over to the
     * prototype web site to learn more. The function takes in an arbitrary
     * number of arguments. The arguments can either be existing classes (ie.
     * Functions) or objects. A class is then returned whose prototype instance
     * has the same properties as the arguments' prototype instance, in the case
     * of functions, or just the arguments' properties, in the case of objects.
     * A special method/property, {@code init}, will be used as the class
     * constructor.
     *
     * @note class is reserved for future use, so I use Class... don't like it
     */
    Class: function() {
        function Klass() {
            this.init.apply(this, arguments);
        }

        for (var i = 0; i < arguments.length; i++) {
            var a = arguments[i];
            xpath.util.extend(Klass.prototype,
                             typeof a == "function" ? a.prototype : a);
        }
        Klass.prototype.init = Klass.prototype.init || function() {};
        return (Klass.prototype.constructor = Klass);
    },

    /**
     * Searches for val in list and returns its index. If val cannot be found in
     * list, then this returns the index at which to insert val, while keeping
     * the list in sorted order. If l or r are given, then this operates on a
     * portion of the list, between [l,r). If cmp is give, then it will be used
     * to compare 2 elements. cmp should be a function that takes 2 arguments, a
     * and b, and returns < 0 if a  0 if a > b. If cmp is not
     * given, then the "natural" ordering (< and ==) is used instead. This is
     * guaranteed to run in O(log n) time, where n = r - l.
     *
     * @param list An array to search for val within
     * @param val The value to search for in the array
     * @param l The lower bound (inclusive) of the array to search in
     * @param r The upper bound (exclusive) of the array to search in
     * @param cmp A comparator to use to determine ordering
     * @return The index of val in the list (or where it should go)
     */
    binarySearch: function(list, val, l, r, cmp) {
        l = l || 0;
        r = (!r || r <= l) ? list.length : r;
        while (l < r) {
            c = Math.floor((l + r) / 2);
            if (list[c] == val)
                return c;
            if (cmp && cmp(list[c], val) < 0 || list[c] < val)
                l = c + 1;
            else
                r = c;
        }
        return l;
    },

    /**
     * Iterate over items in an array.
     */
    each: function(list, cb, data) {
        for (var i = 0, len = list.length; i < len; i++)
            if (cb.call(list[i], i, data) === false)
                return false;
        return true;
    },

    /**
     * Normalize whitespace in a string, as per XPath 1's rules. This will first
     * strip off all leading and trailing whitespace. All consecutive whitespace
     * is then reduced to 1 single space.
     */
    normalizeWhiteSpace: function(str) {
        return str.replace(/(^[\u0020\u0009\u000D\u000A]+|[\u0020\u0009\u000D\u000A]+$)/g, "")
                  .replace(/[\u0020\u0009\u000D\u000A]+/g, " ");
    }
};

})();
<|endoftext|>


<commit_before>
import ExpandableMolecule from './ExpandableMolecule';
import Nmr1dManager from './Nmr1dManager';
import MF from './MF';
import Datas from 'src/main/datas';
import API from 'src/util/api';
import UI from 'src/util/ui';
import {createVar, getData} from './jpaths';
import {elnPlugin} from './libs';
import Roc from '../rest-on-couch/Roc';

const DataObject = Datas.DataObject;

var defaultOptions = {
    varName: 'sample',
    track: true
};

class Sample {
    constructor(couchDB, uuid, options) {
        this.options = Object.assign({}, defaultOptions, options);

        var roc = API.cache('roc');
        if (!roc) {
            roc = new Roc({
                url: couchDB.url,
                database: couchDB.database,
                processor: elnPlugin,
                kind: couchDB.kind
            });
            API.cache('roc', roc);
        }
        this.roc = roc;

        this.uuid = uuid;
        if (!this.uuid) {
            UI.showNotification('Cannot create an editable sample without an uuid', 'error');
            return;
        }
        this._loadInstanceInVisualizer();
    }

    _loadInstanceInVisualizer() {
        this.roc.document(this.uuid, this.options).then(sample => {
            this.sample = sample;
            var sampleVar = API.getVar(this.options.varName);

            createVar(sampleVar, 'sampleCode');
            createVar(sampleVar, 'batchCode');
            createVar(sampleVar, 'creationDate');
            createVar(sampleVar, 'modificationDate');
            createVar(sampleVar, 'content');
            createVar(sampleVar, 'general');
            createVar(sampleVar, 'molfile');
            createVar(sampleVar, 'mf');
            createVar(sampleVar, 'mw');
            createVar(sampleVar, 'em');
            createVar(sampleVar, 'description');
            createVar(sampleVar, 'name');
            createVar(sampleVar, 'physical');
            createVar(sampleVar, 'bp');
            createVar(sampleVar, 'nd');
            createVar(sampleVar, 'mp');
            createVar(sampleVar, 'density');
            createVar(sampleVar, 'ir');
            createVar(sampleVar, 'mass');
            createVar(sampleVar, 'sampleCode');
            createVar(sampleVar, 'sampleCode');
            createVar(sampleVar, 'attachments');

            this.expandableMolecule = new ExpandableMolecule(this.sample, this.options);
            this.nmr1dManager = new Nmr1dManager(this.sample);
            this.nmr1dManager.initializeNMRAssignment();
            createVar(sampleVar, 'nmr');
            this.mf = new MF(this.sample);
            this.mf.fromMF();

            this.onChange = (event) => {
                if (this.options.track && typeof IframeBridge !== 'undefined') {
                    self.IframeBridge.postMessage('tab.status', {
                        saved: false
                    });
                }

                var jpathStr = event.jpath.join('.');

                if (jpathStr.replace(/\.\d+\..*/, '') === '$content.spectra.nmr') {
                    // execute peak picking
                    var currentNmr = this.sample.getChildSync(jpathStr.replace(/(\.\d+)\..*/, '$1').split('.'));
                    this.nmr1dManager.executePeakPicking(currentNmr);
                }

                switch (event.jpath.join('.')) {
                    case '':
                        this.nmr1dManager.initializeNMRAssignment(getData(this.sample, 'nmr'));
                        createVar(sampleVar, 'nmr');
                        break;
                    case '$content.general.molfile':
                        this.mf.fromMolfile();
                        break;
                    case '$content.general.mf':
                        try {
                            this.mf.fromMF();
                            this.nmr1dManager.updateIntegral({mf: true});
                        } catch (e) {
                            // ignore
                        }
                        break;
                    default:
                        break; // ignore
                }
            };

            this.bindChange();
        });
    }

    bindChange() {
        this.sample.unbindChange(this.onChange);
        this.sample.onChange(this.onChange);
    }

    unbindChange() {
        this.sample.unbindChange(this.onChange);
    }

    handleDrop(name) {
        if (!name) {
            throw new Error('handleDrop expects a variable name');
        }
        name = String(name);
        // maps name of variable to type of data
        var types = {
            'droppedNmr': 'nmr',
            'droppedIR': 'ir',
            'droppedMS': 'mass'
        };

        if (!types[name]) {
            throw new Error('Unexpected variable name');
        }

        // Dropped data can be an array
        // Expecting format as from drag and drop module
        var droppedDatas = API.getData(name);
        droppedDatas = droppedDatas.file || droppedDatas.str;
        var prom = Promise.resolve();
        for (let i = 0; i < droppedDatas.length; i++) {
            prom = prom.then(() => {
                var data = DataObject.resurrect(droppedDatas[i]);
                return this.roc.attach(types[name], this.sample, data);
            });
        }
    }

    handleAction(action) {
        if (!action) return;

        if (this.expandableMolecule && this.expandableMolecule.handleAction(action)) return;
        if (this.nmr1dManager && this.nmr1dManager.handleAction(action)) return;

        switch (action.name) {
            case 'save':
                this.roc.update(this.sample).then(function () {
                    if (typeof IframeBridge !== 'undefined') {
                        self.IframeBridge.postMessage('tab.status', {
                            saved: true
                        });
                    }
                });
                break;
            case 'createOptions':
                var advancedOptions1H = API.cache('nmr1hAdvancedOptions');
                if (advancedOptions1H) {
                    API.createData('nmr1hOndeTemplate', API.getData('nmr1hOndeTemplates').full);
                } else {
                    API.createData('nmr1hOndeTemplate', API.getData('nmr1hOndeTemplates').short);
                }
                break;
            case 'deleteAttachment':
                var attachment = action.value.name;
                this.roc.deleteAttachment(this.sample, attachment);
                break;
            case 'deleteNmr':
                this.roc.unattach(this.sample, action.value);
                break;
            case 'attachNMR':
            case 'attachIR':
            case 'attachMass':
                var type = action.name.replace('attach', '').toLowerCase();
                var droppedDatas = action.value;
                droppedDatas = droppedDatas.file || droppedDatas.str;
                var prom = Promise.resolve();
                for (let i = 0; i < droppedDatas.length; i++) {
                    prom = prom.then(() => {
                        const data = DataObject.resurrect(droppedDatas[i]);
                        return this.roc.attach(type, this.sample, data);
                    });
                }
                break;
            case 'refresh':
                UI.confirm('Are you sure you want to refresh? This will discard your local modifications.').then(ok => {
                    if (!ok) return;
                    this.unbindChange();
                    this.roc.discardLocal(this.sample).then(() => {
                        this.nmr1dManager.initializeNMRAssignment(API.getData('currentNmr'));
                        this.expandableMolecule.unbindChange();
                        this.expandableMolecule = new ExpandableMolecule(this.sample, this.options);
                        this.mf = new MF(this.sample);
                        this.mf.fromMF();
                        this.bindChange();
                    });
                    self.IframeBridge.postMessage('tab.status', {
                        saved: true
                    });
                });

                break;
            default:
                break;
        }
    }
}

module.exports = Sample;
<commit_msg>handleDrop: allow type to be custom<commit_after>
import ExpandableMolecule from './ExpandableMolecule';
import Nmr1dManager from './Nmr1dManager';
import MF from './MF';
import Datas from 'src/main/datas';
import API from 'src/util/api';
import UI from 'src/util/ui';
import {createVar, getData} from './jpaths';
import {elnPlugin} from './libs';
import Roc from '../rest-on-couch/Roc';

const DataObject = Datas.DataObject;

var defaultOptions = {
    varName: 'sample',
    track: true
};

class Sample {
    constructor(couchDB, uuid, options) {
        this.options = Object.assign({}, defaultOptions, options);

        var roc = API.cache('roc');
        if (!roc) {
            roc = new Roc({
                url: couchDB.url,
                database: couchDB.database,
                processor: elnPlugin,
                kind: couchDB.kind
            });
            API.cache('roc', roc);
        }
        this.roc = roc;

        this.uuid = uuid;
        if (!this.uuid) {
            UI.showNotification('Cannot create an editable sample without an uuid', 'error');
            return;
        }
        this._loadInstanceInVisualizer();
    }

    _loadInstanceInVisualizer() {
        this.roc.document(this.uuid, this.options).then(sample => {
            this.sample = sample;
            var sampleVar = API.getVar(this.options.varName);

            createVar(sampleVar, 'sampleCode');
            createVar(sampleVar, 'batchCode');
            createVar(sampleVar, 'creationDate');
            createVar(sampleVar, 'modificationDate');
            createVar(sampleVar, 'content');
            createVar(sampleVar, 'general');
            createVar(sampleVar, 'molfile');
            createVar(sampleVar, 'mf');
            createVar(sampleVar, 'mw');
            createVar(sampleVar, 'em');
            createVar(sampleVar, 'description');
            createVar(sampleVar, 'name');
            createVar(sampleVar, 'physical');
            createVar(sampleVar, 'bp');
            createVar(sampleVar, 'nd');
            createVar(sampleVar, 'mp');
            createVar(sampleVar, 'density');
            createVar(sampleVar, 'ir');
            createVar(sampleVar, 'mass');
            createVar(sampleVar, 'sampleCode');
            createVar(sampleVar, 'sampleCode');
            createVar(sampleVar, 'attachments');

            this.expandableMolecule = new ExpandableMolecule(this.sample, this.options);
            this.nmr1dManager = new Nmr1dManager(this.sample);
            this.nmr1dManager.initializeNMRAssignment();
            createVar(sampleVar, 'nmr');
            this.mf = new MF(this.sample);
            this.mf.fromMF();

            this.onChange = (event) => {
                if (this.options.track && typeof IframeBridge !== 'undefined') {
                    self.IframeBridge.postMessage('tab.status', {
                        saved: false
                    });
                }

                var jpathStr = event.jpath.join('.');

                if (jpathStr.replace(/\.\d+\..*/, '') === '$content.spectra.nmr') {
                    // execute peak picking
                    var currentNmr = this.sample.getChildSync(jpathStr.replace(/(\.\d+)\..*/, '$1').split('.'));
                    this.nmr1dManager.executePeakPicking(currentNmr);
                }

                switch (event.jpath.join('.')) {
                    case '':
                        this.nmr1dManager.initializeNMRAssignment(getData(this.sample, 'nmr'));
                        createVar(sampleVar, 'nmr');
                        break;
                    case '$content.general.molfile':
                        this.mf.fromMolfile();
                        break;
                    case '$content.general.mf':
                        try {
                            this.mf.fromMF();
                            this.nmr1dManager.updateIntegral({mf: true});
                        } catch (e) {
                            // ignore
                        }
                        break;
                    default:
                        break; // ignore
                }
            };

            this.bindChange();
        });
    }

    bindChange() {
        this.sample.unbindChange(this.onChange);
        this.sample.onChange(this.onChange);
    }

    unbindChange() {
        this.sample.unbindChange(this.onChange);
    }

    handleDrop(name, type) {
        if (!name) {
            throw new Error('handleDrop expects a variable name');
        }
        name = String(name);
        if(!type) {
            // maps name of variable to type of data
            var types = {
                'droppedNmr': 'nmr',
                'droppedIR': 'ir',
                'droppedMS': 'mass'
            };
            if (!types[name]) {
                throw new Error('Unexpected variable name');
            }
            type = types[name];
        }

        // Dropped data can be an array
        // Expecting format as from drag and drop module
        var droppedDatas = API.getData(name);
        droppedDatas = droppedDatas.file || droppedDatas.str;
        var prom = Promise.resolve();
        for (let i = 0; i < droppedDatas.length; i++) {
            prom = prom.then(() => {
                var data = DataObject.resurrect(droppedDatas[i]);
                return this.roc.attach(type, this.sample, data);
            });
        }
    }

    handleAction(action) {
        if (!action) return;

        if (this.expandableMolecule && this.expandableMolecule.handleAction(action)) return;
        if (this.nmr1dManager && this.nmr1dManager.handleAction(action)) return;

        switch (action.name) {
            case 'save':
                this.roc.update(this.sample).then(function () {
                    if (typeof IframeBridge !== 'undefined') {
                        self.IframeBridge.postMessage('tab.status', {
                            saved: true
                        });
                    }
                });
                break;
            case 'createOptions':
                var advancedOptions1H = API.cache('nmr1hAdvancedOptions');
                if (advancedOptions1H) {
                    API.createData('nmr1hOndeTemplate', API.getData('nmr1hOndeTemplates').full);
                } else {
                    API.createData('nmr1hOndeTemplate', API.getData('nmr1hOndeTemplates').short);
                }
                break;
            case 'deleteAttachment':
                var attachment = action.value.name;
                this.roc.deleteAttachment(this.sample, attachment);
                break;
            case 'deleteNmr':
                this.roc.unattach(this.sample, action.value);
                break;
            case 'attachNMR':
            case 'attachIR':
            case 'attachMass':
                var type = action.name.replace('attach', '').toLowerCase();
                var droppedDatas = action.value;
                droppedDatas = droppedDatas.file || droppedDatas.str;
                var prom = Promise.resolve();
                for (let i = 0; i < droppedDatas.length; i++) {
                    prom = prom.then(() => {
                        const data = DataObject.resurrect(droppedDatas[i]);
                        return this.roc.attach(type, this.sample, data);
                    });
                }
                break;
            case 'refresh':
                UI.confirm('Are you sure you want to refresh? This will discard your local modifications.').then(ok => {
                    if (!ok) return;
                    this.unbindChange();
                    this.roc.discardLocal(this.sample).then(() => {
                        this.nmr1dManager.initializeNMRAssignment(API.getData('currentNmr'));
                        this.expandableMolecule.unbindChange();
                        this.expandableMolecule = new ExpandableMolecule(this.sample, this.options);
                        this.mf = new MF(this.sample);
                        this.mf.fromMF();
                        this.bindChange();
                    });
                    self.IframeBridge.postMessage('tab.status', {
                        saved: true
                    });
                });

                break;
            default:
                break;
        }
    }
}

module.exports = Sample;
<|endoftext|>