text: /*
  * Kendo UI v2014.2.1008 (http://www.telerik.com/kendo-ui)
  * Copyright 2014 Telerik AD. All rights reserved.
  *
  * Kendo UI commercial licenses may be obtained at
  * http://www.telerik.com/purchase/license-agreement/kendo-ui-complete
  * If you do not own a commercial license, this file shall be governed by the trial license terms.
  */
  (function(f, define){
      define([ "./kendo.dataviz.core", "./kendo.dataviz.svg", "./kendo.dataviz.canvas" ], f);
  })(function(){
  
  (function ($, undefined) {
      var kendo = window.kendo,
          extend = $.extend,
          dataviz = kendo.dataviz,
          Widget = kendo.ui.Widget,
          Box2D = dataviz.Box2D,
          terminator = "0000",
          NUMERIC = "numeric",
          ALPHA_NUMERIC = "alphanumeric",
          BYTE = "byte",
          powersOfTwo = {"1": 0},
          powersOfTwoResult = {"0": 1},
          generatorPolynomials = [[1,0],[1,25,0]],
          irregularAlignmentPatternsStartDistance = {15:20,16:20,18:24,19:24,22:20,24:22,26:24,28:20,30:20,31:24,32:28,33:24,36:18,37:22,39:20,40:24},
          versionsCodewordsInformation = [{L:{groups:[[1,19]],totalDataCodewords:19,errorCodewordsPerBlock:7},M:{groups:[[1,16]],totalDataCodewords:16,errorCodewordsPerBlock:10},Q:{groups:[[1,13]],totalDataCodewords:13,errorCodewordsPerBlock:13},H:{groups:[[1,9]],totalDataCodewords:9,errorCodewordsPerBlock:17}},{L:{groups:[[1,34]],totalDataCodewords:34,errorCodewordsPerBlock:10},M:{groups:[[1,28]],totalDataCodewords:28,errorCodewordsPerBlock:16},Q:{groups:[[1,22]],totalDataCodewords:22,errorCodewordsPerBlock:22},H:{groups:[[1,16]],totalDataCodewords:16,errorCodewordsPerBlock:28}},{L:{groups:[[1,55]],totalDataCodewords:55,errorCodewordsPerBlock:15},M:{groups:[[1,44]],totalDataCodewords:44,errorCodewordsPerBlock:26},Q:{groups:[[2,17]],totalDataCodewords:34,errorCodewordsPerBlock:18},H:{groups:[[2,13]],totalDataCodewords:26,errorCodewordsPerBlock:22}},{L:{groups:[[1,80]],totalDataCodewords:80,errorCodewordsPerBlock:20},M:{groups:[[2,32]],totalDataCodewords:64,errorCodewordsPerBlock:18},Q:{groups:[[2,24]],totalDataCodewords:48,errorCodewordsPerBlock:26},H:{groups:[[4,9]],totalDataCodewords:36,errorCodewordsPerBlock:16}},{L:{groups:[[1,108]],totalDataCodewords:108,errorCodewordsPerBlock:26},M:{groups:[[2,43]],totalDataCodewords:86,errorCodewordsPerBlock:24},Q:{groups:[[2,15],[2,16]],totalDataCodewords:62,errorCodewordsPerBlock:18},H:{groups:[[2,11],[2,12]],totalDataCodewords:46,errorCodewordsPerBlock:22}},{L:{groups:[[2,68]],totalDataCodewords:136,errorCodewordsPerBlock:18},M:{groups:[[4,27]],totalDataCodewords:108,errorCodewordsPerBlock:16},Q:{groups:[[4,19]],totalDataCodewords:76,errorCodewordsPerBlock:24},H:{groups:[[4,15]],totalDataCodewords:60,errorCodewordsPerBlock:28}},{L:{groups:[[2,78]],totalDataCodewords:156,errorCodewordsPerBlock:20},M:{groups:[[4,31]],totalDataCodewords:124,errorCodewordsPerBlock:18},Q:{groups:[[2,14],[4,15]],totalDataCodewords:88,errorCodewordsPerBlock:18},H:{groups:[[4,13],[1,14]],totalDataCodewords:66,errorCodewordsPerBlock:26}},{L:{groups:[[2,97]],totalDataCodewords:194,errorCodewordsPerBlock:24},M:{groups:[[2,38],[2,39]],totalDataCodewords:154,errorCodewordsPerBlock:22},Q:{groups:[[4,18],[2,19]],totalDataCodewords:110,errorCodewordsPerBlock:22},H:{groups:[[4,14],[2,15]],totalDataCodewords:86,errorCodewordsPerBlock:26}},{L:{groups:[[2,116]],totalDataCodewords:232,errorCodewordsPerBlock:30},M:{groups:[[3,36],[2,37]],totalDataCodewords:182,errorCodewordsPerBlock:22},Q:{groups:[[4,16],[4,17]],totalDataCodewords:132,errorCodewordsPerBlock:20},H:{groups:[[4,12],[4,13]],totalDataCodewords:100,errorCodewordsPerBlock:24}},{L:{groups:[[2,68],[2,69]],totalDataCodewords:274,errorCodewordsPerBlock:18},M:{groups:[[4,43],[1,44]],totalDataCodewords:216,errorCodewordsPerBlock:26},Q:{groups:[[6,19],[2,20]],totalDataCodewords:154,errorCodewordsPerBlock:24},H:{groups:[[6,15],[2,16]],totalDataCodewords:122,errorCodewordsPerBlock:28}},{L:{groups:[[4,81]],totalDataCodewords:324,errorCodewordsPerBlock:20},M:{groups:[[1,50],[4,51]],totalDataCodewords:254,errorCodewordsPerBlock:30},Q:{groups:[[4,22],[4,23]],totalDataCodewords:180,errorCodewordsPerBlock:28},H:{groups:[[3,12],[8,13]],totalDataCodewords:140,errorCodewordsPerBlock:24}},{L:{groups:[[2,92],[2,93]],totalDataCodewords:370,errorCodewordsPerBlock:24},M:{groups:[[6,36],[2,37]],totalDataCodewords:290,errorCodewordsPerBlock:22},Q:{groups:[[4,20],[6,21]],totalDataCodewords:206,errorCodewordsPerBlock:26},H:{groups:[[7,14],[4,15]],totalDataCodewords:158,errorCodewordsPerBlock:28}},{L:{groups:[[4,107]],totalDataCodewords:428,errorCodewordsPerBlock:26},M:{groups:[[8,37],[1,38]],totalDataCodewords:334,errorCodewordsPerBlock:22},Q:{groups:[[8,20],[4,21]],totalDataCodewords:244,errorCodewordsPerBlock:24},H:{groups:[[12,11],[4,12]],totalDataCodewords:180,errorCodewordsPerBlock:22}},{L:{groups:[[3,115],[1,116]],totalDataCodewords:461,errorCodewordsPerBlock:30},M:{groups:[[4,40],[5,41]],totalDataCodewords:365,errorCodewordsPerBlock:24},Q:{groups:[[11,16],[5,17]],totalDataCodewords:261,errorCodewordsPerBlock:20},H:{groups:[[11,12],[5,13]],totalDataCodewords:197,errorCodewordsPerBlock:24}},{L:{groups:[[5,87],[1,88]],totalDataCodewords:523,errorCodewordsPerBlock:22},M:{groups:[[5,41],[5,42]],totalDataCodewords:415,errorCodewordsPerBlock:24},Q:{groups:[[5,24],[7,25]],totalDataCodewords:295,errorCodewordsPerBlock:30},H:{groups:[[11,12],[7,13]],totalDataCodewords:223,errorCodewordsPerBlock:24}},{L:{groups:[[5,98],[1,99]],totalDataCodewords:589,errorCodewordsPerBlock:24},M:{groups:[[7,45],[3,46]],totalDataCodewords:453,errorCodewordsPerBlock:28},Q:{groups:[[15,19],[2,20]],totalDataCodewords:325,errorCodewordsPerBlock:24},H:{groups:[[3,15],[13,16]],totalDataCodewords:253,errorCodewordsPerBlock:30}},{L:{groups:[[1,107],[5,108]],totalDataCodewords:647,errorCodewordsPerBlock:28},M:{groups:[[10,46],[1,47]],totalDataCodewords:507,errorCodewordsPerBlock:28},Q:{groups:[[1,22],[15,23]],totalDataCodewords:367,errorCodewordsPerBlock:28},H:{groups:[[2,14],[17,15]],totalDataCodewords:283,errorCodewordsPerBlock:28}},{L:{groups:[[5,120],[1,121]],totalDataCodewords:721,errorCodewordsPerBlock:30},M:{groups:[[9,43],[4,44]],totalDataCodewords:563,errorCodewordsPerBlock:26},Q:{groups:[[17,22],[1,23]],totalDataCodewords:397,errorCodewordsPerBlock:28},H:{groups:[[2,14],[19,15]],totalDataCodewords:313,errorCodewordsPerBlock:28}},{L:{groups:[[3,113],[4,114]],totalDataCodewords:795,errorCodewordsPerBlock:28},M:{groups:[[3,44],[11,45]],totalDataCodewords:627,errorCodewordsPerBlock:26},Q:{groups:[[17,21],[4,22]],totalDataCodewords:445,errorCodewordsPerBlock:26},H:{groups:[[9,13],[16,14]],totalDataCodewords:341,errorCodewordsPerBlock:26}},{L:{groups:[[3,107],[5,108]],totalDataCodewords:861,errorCodewordsPerBlock:28},M:{groups:[[3,41],[13,42]],totalDataCodewords:669,errorCodewordsPerBlock:26},Q:{groups:[[15,24],[5,25]],totalDataCodewords:485,errorCodewordsPerBlock:30},H:{groups:[[15,15],[10,16]],totalDataCodewords:385,errorCodewordsPerBlock:28}},{L:{groups:[[4,116],[4,117]],totalDataCodewords:932,errorCodewordsPerBlock:28},M:{groups:[[17,42]],totalDataCodewords:714,errorCodewordsPerBlock:26},Q:{groups:[[17,22],[6,23]],totalDataCodewords:512,errorCodewordsPerBlock:28},H:{groups:[[19,16],[6,17]],totalDataCodewords:406,errorCodewordsPerBlock:30}},{L:{groups:[[2,111],[7,112]],totalDataCodewords:1006,errorCodewordsPerBlock:28},M:{groups:[[17,46]],totalDataCodewords:782,errorCodewordsPerBlock:28},Q:{groups:[[7,24],[16,25]],totalDataCodewords:568,errorCodewordsPerBlock:30},H:{groups:[[34,13]],totalDataCodewords:442,errorCodewordsPerBlock:24}},{L:{groups:[[4,121],[5,122]],totalDataCodewords:1094,errorCodewordsPerBlock:30},M:{groups:[[4,47],[14,48]],totalDataCodewords:860,errorCodewordsPerBlock:28},Q:{groups:[[11,24],[14,25]],totalDataCodewords:614,errorCodewordsPerBlock:30},H:{groups:[[16,15],[14,16]],totalDataCodewords:464,errorCodewordsPerBlock:30}},{L:{groups:[[6,117],[4,118]],totalDataCodewords:1174,errorCodewordsPerBlock:30},M:{groups:[[6,45],[14,46]],totalDataCodewords:914,errorCodewordsPerBlock:28},Q:{groups:[[11,24],[16,25]],totalDataCodewords:664,errorCodewordsPerBlock:30},H:{groups:[[30,16],[2,17]],totalDataCodewords:514,errorCodewordsPerBlock:30}},{L:{groups:[[8,106],[4,107]],totalDataCodewords:1276,errorCodewordsPerBlock:26},M:{groups:[[8,47],[13,48]],totalDataCodewords:1000,errorCodewordsPerBlock:28},Q:{groups:[[7,24],[22,25]],totalDataCodewords:718,errorCodewordsPerBlock:30},H:{groups:[[22,15],[13,16]],totalDataCodewords:538,errorCodewordsPerBlock:30}},{L:{groups:[[10,114],[2,115]],totalDataCodewords:1370,errorCodewordsPerBlock:28},M:{groups:[[19,46],[4,47]],totalDataCodewords:1062,errorCodewordsPerBlock:28},Q:{groups:[[28,22],[6,23]],totalDataCodewords:754,errorCodewordsPerBlock:28},H:{groups:[[33,16],[4,17]],totalDataCodewords:596,errorCodewordsPerBlock:30}},{L:{groups:[[8,122],[4,123]],totalDataCodewords:1468,errorCodewordsPerBlock:30},M:{groups:[[22,45],[3,46]],totalDataCodewords:1128,errorCodewordsPerBlock:28},Q:{groups:[[8,23],[26,24]],totalDataCodewords:808,errorCodewordsPerBlock:30},H:{groups:[[12,15],[28,16]],totalDataCodewords:628,errorCodewordsPerBlock:30}},{L:{groups:[[3,117],[10,118]],totalDataCodewords:1531,errorCodewordsPerBlock:30},M:{groups:[[3,45],[23,46]],totalDataCodewords:1193,errorCodewordsPerBlock:28},Q:{groups:[[4,24],[31,25]],totalDataCodewords:871,errorCodewordsPerBlock:30},H:{groups:[[11,15],[31,16]],totalDataCodewords:661,errorCodewordsPerBlock:30}},{L:{groups:[[7,116],[7,117]],totalDataCodewords:1631,errorCodewordsPerBlock:30},M:{groups:[[21,45],[7,46]],totalDataCodewords:1267,errorCodewordsPerBlock:28},Q:{groups:[[1,23],[37,24]],totalDataCodewords:911,errorCodewordsPerBlock:30},H:{groups:[[19,15],[26,16]],totalDataCodewords:701,errorCodewordsPerBlock:30}},{L:{groups:[[5,115],[10,116]],totalDataCodewords:1735,errorCodewordsPerBlock:30},M:{groups:[[19,47],[10,48]],totalDataCodewords:1373,errorCodewordsPerBlock:28},Q:{groups:[[15,24],[25,25]],totalDataCodewords:985,errorCodewordsPerBlock:30},H:{groups:[[23,15],[25,16]],totalDataCodewords:745,errorCodewordsPerBlock:30}},{L:{groups:[[13,115],[3,116]],totalDataCodewords:1843,errorCodewordsPerBlock:30},M:{groups:[[2,46],[29,47]],totalDataCodewords:1455,errorCodewordsPerBlock:28},Q:{groups:[[42,24],[1,25]],totalDataCodewords:1033,errorCodewordsPerBlock:30},H:{groups:[[23,15],[28,16]],totalDataCodewords:793,errorCodewordsPerBlock:30}},{L:{groups:[[17,115]],totalDataCodewords:1955,errorCodewordsPerBlock:30},M:{groups:[[10,46],[23,47]],totalDataCodewords:1541,errorCodewordsPerBlock:28},Q:{groups:[[10,24],[35,25]],totalDataCodewords:1115,errorCodewordsPerBlock:30},H:{groups:[[19,15],[35,16]],totalDataCodewords:845,errorCodewordsPerBlock:30}},{L:{groups:[[17,115],[1,116]],totalDataCodewords:2071,errorCodewordsPerBlock:30},M:{groups:[[14,46],[21,47]],totalDataCodewords:1631,errorCodewordsPerBlock:28},Q:{groups:[[29,24],[19,25]],totalDataCodewords:1171,errorCodewordsPerBlock:30},H:{groups:[[11,15],[46,16]],totalDataCodewords:901,errorCodewordsPerBlock:30}},{L:{groups:[[13,115],[6,116]],totalDataCodewords:2191,errorCodewordsPerBlock:30},M:{groups:[[14,46],[23,47]],totalDataCodewords:1725,errorCodewordsPerBlock:28},Q:{groups:[[44,24],[7,25]],totalDataCodewords:1231,errorCodewordsPerBlock:30},H:{groups:[[59,16],[1,17]],totalDataCodewords:961,errorCodewordsPerBlock:30}},{L:{groups:[[12,121],[7,122]],totalDataCodewords:2306,errorCodewordsPerBlock:30},M:{groups:[[12,47],[26,48]],totalDataCodewords:1812,errorCodewordsPerBlock:28},Q:{groups:[[39,24],[14,25]],totalDataCodewords:1286,errorCodewordsPerBlock:30},H:{groups:[[22,15],[41,16]],totalDataCodewords:986,errorCodewordsPerBlock:30}},{L:{groups:[[6,121],[14,122]],totalDataCodewords:2434,errorCodewordsPerBlock:30},M:{groups:[[6,47],[34,48]],totalDataCodewords:1914,errorCodewordsPerBlock:28},Q:{groups:[[46,24],[10,25]],totalDataCodewords:1354,errorCodewordsPerBlock:30},H:{groups:[[2,15],[64,16]],totalDataCodewords:1054,errorCodewordsPerBlock:30}},{L:{groups:[[17,122],[4,123]],totalDataCodewords:2566,errorCodewordsPerBlock:30},M:{groups:[[29,46],[14,47]],totalDataCodewords:1992,errorCodewordsPerBlock:28},Q:{groups:[[49,24],[10,25]],totalDataCodewords:1426,errorCodewordsPerBlock:30},H:{groups:[[24,15],[46,16]],totalDataCodewords:1096,errorCodewordsPerBlock:30}},{L:{groups:[[4,122],[18,123]],totalDataCodewords:2702,errorCodewordsPerBlock:30},M:{groups:[[13,46],[32,47]],totalDataCodewords:2102,errorCodewordsPerBlock:28},Q:{groups:[[48,24],[14,25]],totalDataCodewords:1502,errorCodewordsPerBlock:30},H:{groups:[[42,15],[32,16]],totalDataCodewords:1142,errorCodewordsPerBlock:30}},{L:{groups:[[20,117],[4,118]],totalDataCodewords:2812,errorCodewordsPerBlock:30},M:{groups:[[40,47],[7,48]],totalDataCodewords:2216,errorCodewordsPerBlock:28},Q:{groups:[[43,24],[22,25]],totalDataCodewords:1582,errorCodewordsPerBlock:30},H:{groups:[[10,15],[67,16]],totalDataCodewords:1222,errorCodewordsPerBlock:30}},{L:{groups:[[19,118],[6,119]],totalDataCodewords:2956,errorCodewordsPerBlock:30},M:{groups:[[18,47],[31,48]],totalDataCodewords:2334,errorCodewordsPerBlock:28},Q:{groups:[[34,24],[34,25]],totalDataCodewords:1666,errorCodewordsPerBlock:30},H:{groups:[[20,15],[61,16]],totalDataCodewords:1276,errorCodewordsPerBlock:30}}],
          finderPattern = [1,0,1,1,1],
          alignmentPattern = [1,0,1],
          errorCorrectionPatterns = {L: "01", M: "00", Q: "11", H: "10"},
          formatMaskPattern = "101010000010010",
          formatGeneratorPolynomial = "10100110111",
          versionGeneratorPolynomial = "1111100100101",
          paddingCodewords = ["11101100", "00010001"],
          finderPatternValue = 93,
          maskPatternConditions = [
              function(row,column){return (row + column) % 2 === 0;},
              function(row){return row % 2 === 0;},
              function(row,column){return column % 3 === 0;},
              function(row,column){return (row + column) % 3 === 0;},
              function(row,column){return (Math.floor(row/2) + Math.floor(column/3)) % 2 === 0;},
              function(row,column){return ((row * column) % 2) + ((row * column) % 3) === 0;},
              function(row,column){return (((row * column) % 2) + ((row * column) % 3)) % 2 === 0;},
              function(row,column){return (((row + column) % 2) + ((row * column) % 3)) % 2 === 0;}
          ],
          numberRegex = /^\d+/,
          alphaPattern = "A-Z0-9 $%*+./:-",
          alphaExclusiveSet = "A-Z $%*+./:-",
          alphaRegex = new RegExp("^[" + alphaExclusiveSet + "]+"),
          alphaNumericRegex = new RegExp("^[" + alphaPattern+ "]+"),
          byteRegex = new RegExp("^[^" + alphaPattern+ "]+"),
          initMinNumericBeforeAlpha = 8,
          initMinNumericBeforeByte = 5,
          initMinAlphaBeforeByte = 8,
          minNumericBeforeAlpha = 17,
          minNumericBeforeByte = 9,
          minAlphaBeforeByte =  16,
          round = Math.round;
  
          function toDecimal(value){
              return parseInt(value, 2);
          }
  
          function toBitsString(value, length){
              var result = Number(value).toString(2);
              if(result.length < length){
                  result = new Array(length - result.length + 1).join(0) + result;
              }
              return result;
          }
  
          function splitInto(str, n){
              var result = [],
                  idx = 0;
              while(idx < str.length){
                  result.push(str.substring(idx, idx + n));
                  idx+= n;
              }
              return result;
          }
  
          var QRDataMode = kendo.Class.extend({
              getVersionIndex: function(version){
                  if(version < 10){
                      return 0;
                  }
                  else if(version > 26){
                      return 2;
                  }
  
                  return 1;
              },
              getBitsCharacterCount: function(version){
                  var mode = this;
                  return mode.bitsInCharacterCount[mode.getVersionIndex(version || 40)];
              },
              getModeCountString: function(length, version){
                  var mode = this;
                  return mode.modeIndicator + toBitsString(length, mode.getBitsCharacterCount(version));
              },
              encode: function(){},
              getStringBitsLength: function(){},
              getValue: function(){},
              modeIndicator: "",
              bitsInCharacterCount: []
          });
  
          var modes = {};
          modes[NUMERIC] = QRDataMode.extend({
              bitsInCharacterCount: [10, 12, 14],
              modeIndicator: "0001",
              getValue: function(character){
                  return parseInt(character, 10);
              },
              encode: function(str, version){
                  var mode = this,
                      parts = splitInto(str, 3),
                      result = mode.getModeCountString(str.length, version);
  
                  for(var i = 0; i < parts.length - 1; i++){
                      result += toBitsString(parts[i], 10);
                  }
                  return result + toBitsString(parts[i], 1 + 3 * parts[i].length);
              },
              getStringBitsLength: function(inputLength, version){
                  var mod3 = inputLength % 3;
                  return 4 + this.getBitsCharacterCount(version) + 10 * Math.floor(inputLength / 3) + 3 * mod3 + (mod3 === 0 ? 0 : 1);
              }
          });
  
          modes[ALPHA_NUMERIC] = QRDataMode.extend({
              characters: {"0":0,"1": 1,"2": 2,"3": 3,"4": 4,"5": 5,"6": 6,"7": 7,"8": 8,"9": 9,"A": 10,"B": 11,"C": 12,"D": 13,"E": 14,"F": 15,"G": 16,"H": 17,"I": 18,"J": 19,"K": 20,"L": 21,"M": 22,"N": 23,"O": 24,"P": 25,"Q": 26,"R": 27,"S": 28,"T": 29,"U": 30,"V": 31,"W": 32,"X": 33,"Y": 34,"Z": 35," ": 36,"$": 37,"%": 38,"*": 39,"+": 40,"-": 41,".": 42,"/": 43,":": 44},
              bitsInCharacterCount: [9,11,13],
              modeIndicator: "0010",
              getValue: function(character){
                  return this.characters[character];
              },
              encode: function(str, version){
                  var mode = this,
                      parts = splitInto(str, 2),
                      result = mode.getModeCountString(str.length, version),
                      value;
                  for(var i = 0; i < parts.length - 1; i++){
                      value = 45 * mode.getValue(parts[i].charAt(0)) + mode.getValue(parts[i].charAt(1));
                      result += toBitsString(value, 11);
                  }
                  value = parts[i].length == 2 ?
                      45 * mode.getValue(parts[i].charAt(0)) + mode.getValue(parts[i].charAt(1)) :
                      mode.getValue(parts[i].charAt(0));
                  return result + toBitsString(value, 1 + 5 * parts[i].length);
              },
              getStringBitsLength: function(inputLength, version){
                  return 4 + this.getBitsCharacterCount(version) + 11 * Math.floor(inputLength / 2) + 6 * (inputLength % 2);
              }
          });
  
          modes[BYTE] = QRDataMode.extend({
              bitsInCharacterCount: [8,16,16],
              modeIndicator: "0100",
              getValue: function(character){
                  var code = character.charCodeAt(0);
                  if(code <= 127 || (160 <= code && code <= 255)){
                      return code;
                  }
                  else{
                      throw new Error("Unsupported character: " + character);
                  }
              },
              encode: function(str, version){
                  var mode = this,
                      result = mode.getModeCountString(str.length, version);
  
                  for(var i = 0; i < str.length; i++){
                      result += toBitsString(mode.getValue(str.charAt(i)), 8);
                  }
                  return result;
              },
              getStringBitsLength: function(inputLength, version){
                  return 4 + this.getBitsCharacterCount(version) + 8 * inputLength;
              }
          });
  
          var modeInstances = {};
          for(var mode in modes){
              modeInstances[mode] = new modes[mode]();
          }
  
          var FreeCellVisitor = function (matrix){
              var that = this,
                  row = matrix.length - 1,
                  column = matrix.length - 1,
                  startColumn = column,
                  dir = -1,
                  c = 0;
              that.move = function(){
                  row += dir * c;
                  c^=1;
                  column = startColumn - c;
              };
              that.getNextCell = function(){
                  while(matrix[row][column] !== undefined){
                      that.move();
                      if(row < 0 || row >= matrix.length){
                          dir = -dir;
                          startColumn-= startColumn != 8 ? 2 : 3;
                          column = startColumn;
                          row = dir < 0 ? matrix.length - 1 : 0;
                      }
                  }
                  return {row: row, column: column};
              };
              that.getNextRemainderCell = function(){
                  that.move();
                  if(matrix[row][column] === undefined){
                       return {row: row, column: column};
                  }
              };
          };
  
          function fillFunctionCell(matrices, bit, x, y){
              for(var i = 0; i< matrices.length;i++){
                  matrices[i][x][y] = bit;
              }
          }
  
          function fillDataCell(matrices, bit, x, y){
              for(var i = 0; i < maskPatternConditions.length;i++){
                  matrices[i][x][y] = maskPatternConditions[i](x,y) ? bit ^ 1 : parseInt(bit, 10);
              }
          }
  
          var fillData = function (matrices, blocks){
              var cellVisitor = new FreeCellVisitor(matrices[0]),
                  block,
                  codewordIdx,
                  cell;
  
              for(var blockIdx = 0; blockIdx < blocks.length;blockIdx++){
                  block = blocks[blockIdx];
                  codewordIdx = 0;
                  while(block.length > 0){
                      for(var i = 0; i< block.length; i++){
                           for(var j = 0; j < 8;j++){
                              cell = cellVisitor.getNextCell();
                              fillDataCell(matrices, block[i][codewordIdx].charAt(j), cell.row, cell.column);
                          }
                      }
  
                      codewordIdx++;
                      while(block[0] && codewordIdx == block[0].length){
                          block.splice(0,1);
                      }
                  }
              }
  
              while((cell = cellVisitor.getNextRemainderCell())){
                  fillDataCell(matrices, 0, cell.row, cell.column);
              }
          };
  
          var padDataString = function (dataString, totalDataCodewords){
              var dataBitsCount = totalDataCodewords * 8,
                  terminatorIndex = 0,
                  paddingCodewordIndex = 0;
              while(dataString.length < dataBitsCount && terminatorIndex < terminator.length){
                  dataString+=terminator.charAt(terminatorIndex++);
              }
  
              if(dataString.length % 8 !== 0){
                  dataString+= new Array(9 - dataString.length % 8).join("0");
              }
  
              while(dataString.length < dataBitsCount){
                  dataString+= paddingCodewords[paddingCodewordIndex];
                  paddingCodewordIndex ^= 1;
              }
              return dataString;
          };
  
          function generatePowersOfTwo(){
              var result;
              for(var power = 1; power < 255; power++){
  
                  result =  powersOfTwoResult[power - 1] * 2;
                  if(result > 255){
                      result = result ^ 285;
                  }
  
                  powersOfTwoResult[power] = result;
                  powersOfTwo[result] = power;
              }
  
              result = (powersOfTwoResult[power - 1] * 2) ^ 285;
              powersOfTwoResult[power] =   result;
              powersOfTwoResult[-1] = 0;
          }
  
          var xorPolynomials = function (x,y){
              var result = [],
                  idx = x.length - 2;
              for(var i = idx; i>=0; i--){
                   result[i] = x[i] ^ y[i];
              }
  
              return result;
          };
  
          var multiplyPolynomials = function (x, y){
              var result = [];
              for(var i = 0; i < x.length; i++){
                  for(var j = 0; j < y.length; j++){
                      if(result[i+j] === undefined){
                           result[i+j] = (x[i] + (y[j] >= 0 ? y[j] : 0)) % 255;
                      }
                      else{
                         result[i+j] = powersOfTwo[powersOfTwoResult[result[i+j]] ^ powersOfTwoResult[(x[i] + y[j]) % 255]];
                      }
                  }
              }
  
              return result;
          };
  
          function generateGeneratorPolynomials(){
              var maxErrorCorrectionCodeWordsCount = 68;
              for(var idx = 2; idx <= maxErrorCorrectionCodeWordsCount; idx++){
                  var firstPolynomial = generatorPolynomials[idx - 1],
                      secondPolynomial = [idx, 0];
                  generatorPolynomials[idx] =  multiplyPolynomials(firstPolynomial, secondPolynomial);
              }
          }
  
          //possibly generate on demand
          generatePowersOfTwo();
          generateGeneratorPolynomials();
  
          function multiplyByConstant(polynomial, power){
              var result = [],
                  idx = polynomial.length - 1;
              do{
                  result[idx] = powersOfTwoResult[(polynomial[idx] + power) % 255];
                  idx--;
              }while(polynomial[idx] !== undefined);
  
              return result;
          }
  
          var generateErrorCodewords = function (data, errorCodewordsCount){
              var generator = generatorPolynomials[errorCodewordsCount - 1],
                  result = new Array(errorCodewordsCount).concat(data),
                  generatorPolynomial = new Array(result.length - generator.length).concat(generator),
                  steps = data.length,
                  errorCodewords = [],
                  divisor,
                  idx;
  
              for(idx = 0; idx < steps; idx++){
                  divisor = multiplyByConstant(generatorPolynomial, powersOfTwo[result[result.length - 1]]);
                  generatorPolynomial.splice(0,1);
  
                  result = xorPolynomials(divisor, result);
              }
  
              for(idx = result.length - 1; idx >= 0;idx--){
                  errorCodewords[errorCodewordsCount - 1 - idx] = toBitsString(result[idx], 8);
              }
  
              return errorCodewords;
          };
  
          var getBlocks = function (dataStream, versionCodewordsInformation){
              var codewordStart = 0,
                  dataBlocks = [],
                  errorBlocks = [],
                  dataBlock,
                  versionGroups = versionCodewordsInformation.groups,
                  blockCodewordsCount,
                  groupBlocksCount,
                  messagePolynomial,
                  codeword;
  
              for(var groupIdx = 0; groupIdx < versionGroups.length; groupIdx++){
                  groupBlocksCount = versionGroups[groupIdx][0];
                  for(var blockIdx = 0; blockIdx < groupBlocksCount;blockIdx++){
                      blockCodewordsCount = versionGroups[groupIdx][1];
                      dataBlock = [];
                      messagePolynomial = [];
                      for(var codewordIdx = 1; codewordIdx <= blockCodewordsCount; codewordIdx++){
                          codeword = dataStream.substring(codewordStart, codewordStart + 8);
                          dataBlock.push(codeword);
                          messagePolynomial[blockCodewordsCount - codewordIdx] = toDecimal(codeword);
                          codewordStart+=8;
                      }
                      dataBlocks.push(dataBlock);
                      errorBlocks.push(generateErrorCodewords(messagePolynomial,
                          versionCodewordsInformation.errorCodewordsPerBlock));
                  }
              }
              return [dataBlocks, errorBlocks];
          };
  
          var chooseMode = function (str, minNumericBeforeAlpha, minNumericBeforeByte, minAlphaBeforeByte, previousMode){
               var numeric = numberRegex.exec(str),
                  numericMatch = numeric ? numeric[0] : "",
                  alpha = alphaRegex.exec(str),
                  alphaMatch = alpha ? alpha[0] : "",
                  alphaNumeric = alphaNumericRegex.exec(str),
                  alphaNumericMatch = alphaNumeric ? alphaNumeric[0] : "",
                  mode,
                  modeString;
  
               if(numericMatch && (numericMatch.length >= minNumericBeforeAlpha ||
                       str.length == numericMatch.length || (numericMatch.length >= minNumericBeforeByte &&
                       !alphaNumericRegex.test(str.charAt(numericMatch.length))))){
                  mode = NUMERIC;
                  modeString = numericMatch;
               }
               else if(alphaNumericMatch && (str.length == alphaNumericMatch.length ||
                  alphaNumericMatch.length >= minAlphaBeforeByte || previousMode == ALPHA_NUMERIC)){
                  mode = ALPHA_NUMERIC;
                  modeString =  numericMatch || alphaMatch;
               }
               else {
                  mode = BYTE;
                  if(alphaNumericMatch){
                      modeString = alphaNumericMatch + byteRegex.exec(str.substring(alphaNumericMatch.length))[0];
                  }
                  else{
                      modeString = byteRegex.exec(str)[0];
                  }
               }
  
               return {
                  mode: mode,
                  modeString: modeString
               };
          };
  
          var getModes = function (str){
              var modes = [],
                  previousMode,
                  idx = 0;
              modes.push(chooseMode(str, initMinNumericBeforeAlpha, initMinNumericBeforeByte, initMinAlphaBeforeByte, previousMode));
              previousMode = modes[0].mode;
              str = str.substr(modes[0].modeString.length);
  
              while(str.length > 0){
                 var nextMode = chooseMode(str, minNumericBeforeAlpha, minNumericBeforeByte, minAlphaBeforeByte, previousMode);
                 if(nextMode.mode != previousMode){
                      previousMode = nextMode.mode;
                      modes.push(nextMode);
                      idx++;
                 }
                 else{
                      modes[idx].modeString += nextMode.modeString;
                 }
                 str = str.substr(nextMode.modeString.length);
              }
  
              return modes;
          };
  
          var getDataCodewordsCount = function (modes){
              var length = 0,
                  mode;
              for(var i = 0; i < modes.length; i++){
                  mode = modeInstances[modes[i].mode];
                  length+= mode.getStringBitsLength(modes[i].modeString.length);
              }
  
              return Math.ceil(length / 8);
          };
  
          var getVersion = function (dataCodewordsCount, errorCorrectionLevel){
              var x = 0,
                  y = versionsCodewordsInformation.length - 1,
                  version = Math.floor(versionsCodewordsInformation.length / 2);
  
              do{
                  if(dataCodewordsCount < versionsCodewordsInformation[version][errorCorrectionLevel].totalDataCodewords){
                      y = version;
                  }
                  else{
                      x = version;
                  }
                  version = x + Math.floor((y - x) / 2);
  
              }while(y - x > 1);
  
              if(dataCodewordsCount <= versionsCodewordsInformation[x][errorCorrectionLevel].totalDataCodewords){
                  return version + 1;
              }
              return y + 1;
          };
  
          var getDataString = function (modes, version){
              var dataString = "",
                  mode;
              for(var i = 0; i < modes.length; i++){
                  mode = modeInstances[modes[i].mode];
                  dataString+= mode.encode(modes[i].modeString, version);
              }
  
              return dataString;
          };
  
          //fix case all zeros
          var encodeFormatInformation = function (format){
              var formatNumber = toDecimal(format),
                  encodedString,
                  result = "";
              if(formatNumber === 0){
                  return "101010000010010";
              }
              else{
                  encodedString = encodeBCH(toDecimal(format), formatGeneratorPolynomial, 15);
              }
              for(var i = 0; i < encodedString.length; i++){
                  result += encodedString.charAt(i) ^ formatMaskPattern.charAt(i);
              }
  
              return result;
          };
  
          var encodeBCH = function (value, generatorPolynomial, codeLength){
              var generatorNumber = toDecimal(generatorPolynomial),
                  polynomialLength = generatorPolynomial.length - 1,
                  valueNumber = value << polynomialLength,
                  length = codeLength - polynomialLength,
                  valueString = toBitsString(value, length),
                  result = dividePolynomials(valueNumber, generatorNumber);
              result = valueString + toBitsString(result, polynomialLength);
              return result;
          };
  
          var dividePolynomials = function (numberX,numberY){
                  var yLength = numberY.toString(2).length,
                      xLength = numberX.toString(2).length;
                  do{
                      numberX ^= numberY << xLength - yLength;
                      xLength = numberX.toString(2).length;
                  }
                  while(xLength >= yLength);
  
                  return numberX;
          };
  
          function getNumberAt(str, idx){
              return parseInt(str.charAt(idx), 10);
          }
  
          var initMatrices = function (version){
              var matrices = [],
                  modules =  17 + 4 * version;
              for(var i = 0; i < maskPatternConditions.length; i++){
                  matrices[i] = new Array(modules);
                  for(var j = 0; j < modules; j++){
                      matrices[i][j] = new Array(modules);
                  }
              }
  
              return matrices;
          };
  
          var addFormatInformation =function (matrices, formatString){
              var matrix = matrices[0],
                  x,
                  y,
                  idx = 0,
                  length = formatString.length;
  
              for(x=0, y=8; x <= 8;x++){
                  if(x!== 6){
                      fillFunctionCell(matrices, getNumberAt(formatString, length - 1 - idx++), x, y);
                  }
              }
  
              for(x=8, y=7; y>=0;y--){
                  if(y!== 6){
                      fillFunctionCell(matrices, getNumberAt(formatString, length - 1 - idx++), x, y);
                  }
              }
              idx=0;
              for(y = matrix.length - 1, x = 8; y >= matrix.length - 8;y--){
                  fillFunctionCell(matrices,getNumberAt(formatString, length - 1 - idx++), x, y);
              }
  
              fillFunctionCell(matrices, 1, matrix.length - 8, 8);
  
              for(x = matrix.length - 7, y = 8; x < matrix.length;x++){
                  fillFunctionCell(matrices, getNumberAt(formatString, length - 1 - idx++), x, y);
              }
          };
  
          var encodeVersionInformation = function (version){
              return encodeBCH(version, versionGeneratorPolynomial, 18);
          };
  
          var addVersionInformation = function (matrices, dataString){
              var matrix = matrices[0],
                  modules = matrix.length,
                  x1 = 0,
                  y1 = modules - 11,
                  x2 = modules - 11,
                  y2 = 0,
                  quotient,
                  mod,
                  value;
  
              for(var idx =0; idx < dataString.length; idx++){
                  quotient = Math.floor(idx / 3);
                  mod = idx % 3;
                  value = getNumberAt(dataString, dataString.length - idx - 1);
                  fillFunctionCell(matrices, value, x1 + quotient, y1 + mod);
                  fillFunctionCell(matrices, value, x2 + mod, y2 + quotient);
              }
          };
  
          var addCentricPattern = function (matrices, pattern, x, y){
              var size = pattern.length + 2,
                  length = pattern.length + 1,
                  value;
  
              for(var i = 0; i < pattern.length; i++){
                  for(var j = i; j < size - i; j++){
                      value = pattern[i];
                      fillFunctionCell(matrices, value, x + j, y + i);
                      fillFunctionCell(matrices, value, x + i, y + j);
                      fillFunctionCell(matrices, value, x + length - j, y + length - i);
                      fillFunctionCell(matrices, value, x + length - i, y + length - j);
                  }
              }
          };
  
          var addFinderSeparator = function (matrices, direction, x, y){
              var nextX = x,
                  nextY = y,
                  matrix = matrices[0];
              do{
                  fillFunctionCell(matrices, 0, nextX, y);
                  fillFunctionCell(matrices, 0, x, nextY);
                  nextX+= direction[0];
                  nextY+= direction[1];
              }
              while(nextX >=0 && nextX < matrix.length);
          };
  
          var addFinderPatterns = function (matrices){
              var modules = matrices[0].length;
              addCentricPattern(matrices, finderPattern, 0, 0);
              addFinderSeparator(matrices, [-1,-1], 7,7);
              addCentricPattern(matrices, finderPattern, modules - 7, 0);
              addFinderSeparator(matrices, [1,-1], modules - 8, 7);
              addCentricPattern(matrices, finderPattern, 0 , modules - 7);
              addFinderSeparator(matrices, [-1,1],7, modules - 8);
          };
  
          var addAlignmentPatterns = function (matrices, version){
              if(version < 2) {
                  return;
              }
  
              var matrix = matrices[0],
                  modules = matrix.length,
                  pointsCount = Math.floor(version / 7),
                  points = [6],
                  startDistance,
                  distance,
                  idx = 0;
  
              if((startDistance = irregularAlignmentPatternsStartDistance[version])){
                  distance = (modules - 13 - startDistance) / pointsCount;
              }
              else{
                  startDistance = distance = (modules - 13) / (pointsCount + 1);
              }
              points.push(points[idx++] + startDistance);
              while((points[idx] + distance) < modules){
                  points.push(points[idx++] + distance);
              }
              for(var i = 0; i < points.length;i++){
                  for(var j = 0; j < points.length; j++){
                      if(matrix[points[i]][points[j]] === undefined){
                          addCentricPattern(matrices, alignmentPattern, points[i] - 2, points[j] - 2);
                      }
                  }
              }
          };
  
          var addTimingFunctions = function (matrices){
              var row = 6,
                  column = 6,
                  value = 1,
                  modules = matrices[0].length;
              for(var i = 8; i < modules - 8;i++){
                  fillFunctionCell(matrices, value, row, i);
                  fillFunctionCell(matrices, value, i, column);
                  value ^= 1;
              }
          };
  
          var scoreMaskMatrixes = function (matrices){
              var scores = [],
                  previousBits = [],
                  darkModules =  [],
                  patterns = [],
                  adjacentSameBits = [],
                  matrix,
                  i,
                  row = 0,
                  column = 1,
                  modules = matrices[0].length;
  
  
              for(i = 0; i < matrices.length; i++){
                  scores[i] = 0;
                  darkModules[i] = 0;
                  adjacentSameBits[i] = [0,0];
                  patterns[i] = [0, 0];
                  previousBits[i] = [];
              }
              for(i = 0; i < modules; i++){
                  for(var j = 0; j < modules; j++){
                      for(var k = 0; k < matrices.length; k++){
                          matrix = matrices[k];
                          darkModules[k]+= parseInt(matrix[i][j], 10);
                          if(previousBits[k][row] === matrix[i][j] && i + 1 < modules && j - 1 >= 0 &&
                              matrix[i + 1][j] == previousBits[k][row] && matrix[i + 1][j - 1] == previousBits[k][row]){
                              scores[k]+=3;
                          }
                          scoreFinderPatternOccurance(k, patterns, scores, row, matrix[i][j]);
                          scoreFinderPatternOccurance(k, patterns, scores, column, matrix[j][i]);
                          scoreAdjacentSameBits(k,scores,previousBits,matrix[i][j],adjacentSameBits,row);
                          scoreAdjacentSameBits(k,scores,previousBits,matrix[j][i],adjacentSameBits,column);
                      }
                  }
              }
              var total = modules * modules,
                  minIdx,
                  min = Number.MAX_VALUE;
  
              for(i = 0; i < scores.length; i++){
                  scores[i]+= calculateDarkModulesRatioScore(darkModules[i], total);
                  if(scores[i] < min){
                      min = scores[i];
                      minIdx = i;
                  }
              }
  
              return minIdx;
          };
  
          function scoreFinderPatternOccurance(idx, patterns, scores, rowColumn, bit){
              patterns[idx][rowColumn] = ((patterns[idx][rowColumn] << 1) ^ bit) % 128;
              if(patterns[idx][rowColumn] == finderPatternValue){
                  scores[idx] += 40;
              }
          }
  
          function scoreAdjacentSameBits(idx, scores, previousBits, bit, adjacentBits, rowColumn){
              if(previousBits[idx][rowColumn] == bit){
                  adjacentBits[idx][rowColumn]++;
              }
              else{
                  previousBits[idx][rowColumn] = bit;
                  if(adjacentBits[idx][rowColumn] >= 5){
                      scores[idx]+= 3 + adjacentBits[idx][rowColumn] - 5;
                  }
                  adjacentBits[idx][rowColumn] = 1;
              }
          }
  
          function calculateDarkModulesRatioScore(darkModules, total){
              var percent = Math.floor((darkModules / total) * 100),
                  mod5 = percent % 5,
                  previous = Math.abs(percent - mod5 - 50),
                  next = Math.abs(percent +  5 - mod5 - 50),
                  score = 10 * Math.min(previous / 5, next / 5);
              return score;
          }
  
          var EncodingResult = function(dataString, version){
              this.dataString = dataString;
              this.version = version;
          };
  
          var IsoEncoder = function(){
              this.getEncodingResult = function(inputString, errorCorrectionLevel){
                  var modes = getModes(inputString),
                  dataCodewordsCount = getDataCodewordsCount(modes),
                  version = getVersion(dataCodewordsCount, errorCorrectionLevel),
                  dataString = getDataString(modes, version);
  
                  return new EncodingResult(dataString, version);
              };
          };
  
          var UTF8Encoder = function(){
              this.mode = modeInstances[this.encodingMode];
          };
  
          UTF8Encoder.fn = UTF8Encoder.prototype = {
              encodingMode: BYTE,
              utfBOM: "111011111011101110111111",
              initialModeCountStringLength: 20,
              getEncodingResult: function(inputString, errorCorrectionLevel){
                  var that = this,
                      data = that.encode(inputString),
                      dataCodewordsCount = that.getDataCodewordsCount(data),
                      version = getVersion(dataCodewordsCount, errorCorrectionLevel),
                      dataString = that.mode.getModeCountString(data.length / 8, version) + data;
  
                  return new EncodingResult(dataString, version);
              },
              getDataCodewordsCount: function(data){
                  var that = this,
                      dataLength = data.length,
                      dataCodewordsCount = Math.ceil(( that.initialModeCountStringLength + dataLength) / 8);
  
                  return dataCodewordsCount;
              },
              encode: function(str){
                  var that = this,
                      result = that.utfBOM;
                  for(var i = 0; i < str.length; i++){
                      result += that.encodeCharacter(str.charCodeAt(i));
                  }
                  return result;
              },
              encodeCharacter: function(code){
                  var bytesCount = this.getBytesCount(code),
                      bc = bytesCount - 1,
                      result = "";
  
                  if(bytesCount == 1){
                      result = toBitsString(code, 8);
                  }
                  else{
                      var significantOnes = 8 - bytesCount;
  
                      for(var i = 0; i < bc; i++){
                          result = toBitsString(code >> (i * 6) & 63 | 128, 8) + result;
                      }
  
                      result = ((code >> bc * 6) | ((255 >> significantOnes) << significantOnes)).toString(2) + result;
                  }
                  return result;
              },
              getBytesCount: function(code){
                  var ranges = this.ranges;
                  for(var i = 0; i < ranges.length;i++){
                      if(code < ranges[i]){
                          return i + 1;
                      }
                  }
              },
              ranges: [128,2048,65536,2097152,67108864]
          };
  
          var QRCodeDataEncoder = function(encoding){
              if(encoding && encoding.toLowerCase().indexOf("utf_8") >= 0){
                  return new UTF8Encoder();
              }
              else{
                  return new IsoEncoder();
              }
          };
  
          var encodeData = function (inputString, errorCorrectionLevel, encoding){
              var encoder = new QRCodeDataEncoder(encoding),
                  encodingResult = encoder.getEncodingResult(inputString, errorCorrectionLevel),
                  version = encodingResult.version,
                  versionInformation = versionsCodewordsInformation[version - 1][errorCorrectionLevel],
                  dataString = padDataString(encodingResult.dataString, versionInformation.totalDataCodewords),
                  blocks = getBlocks(dataString, versionInformation),
                  matrices = initMatrices(version);
  
              addFinderPatterns(matrices);
              addAlignmentPatterns(matrices, version);
              addTimingFunctions(matrices);
  
              if(version >= 7){
                  addVersionInformation(matrices, toBitsString(0, 18));
              }
  
              addFormatInformation(matrices, toBitsString(0, 15));
              fillData(matrices, blocks);
  
              var minIdx = scoreMaskMatrixes(matrices),
                  optimalMatrix = matrices[minIdx];
  
              if(version >= 7){
                  addVersionInformation([optimalMatrix], encodeVersionInformation(version));
              }
  
              var formatString = errorCorrectionPatterns[errorCorrectionLevel] + toBitsString(minIdx, 3);
              addFormatInformation([optimalMatrix], encodeFormatInformation(formatString));
  
              return optimalMatrix;
          };
  
          var QRCodeDefaults= {
              DEFAULT_SIZE: 200,
              QUIET_ZONE_LENGTH: 4,
              DEFAULT_ERROR_CORRECTION_LEVEL:"L",
              DEFAULT_BACKGROUND: "#fff",
              DEFAULT_DARK_MODULE_COLOR: "#000",
              MIN_BASE_UNIT_SIZE: 1
          };
  
          var QRCode = Widget.extend({
              init: function (element, options) {
                  var that = this;
  
                  Widget.fn.init.call(that, element, options);
  
                  that.element = $(element);
                  that.wrapper = that.element;
                  that.element.addClass("k-qrcode");
                  that._view = dataviz.ViewFactory.current.create({}, that.options.renderAs);
                  that.setOptions(options);
              },
  
              redraw: function(){
                  var that = this,
                      view = that._view;
  
                  that._redraw(view);
                  view.renderTo(that.element[0]);
              },
  
              svg: function() {
                  if (dataviz.SVGView) {
                      var view = new dataviz.SVGView();
  
                      this._redraw(view);
  
                      return view.render();
                  } else {
                      throw new Error("Unable to create SVGView. Check that kendo.dataviz.svg.js is loaded.");
                  }
              },
  
              imageDataURL: function() {
                  if (dataviz.CanvasView) {
                      if (dataviz.supportsCanvas()) {
                          var container = document.createElement("div"),
                              view = new dataviz.CanvasView();
  
                          this._redraw(view);
  
                          return view.renderTo(container).toDataURL();
                      } else {
                          kendo.logToConsole(
                              "Warning: Unable to generate image. The browser does not support Canvas.\n" +
                              "User agent: " + navigator.userAgent);
  
                          return null;
                      }
                  } else {
                      throw new Error("Unable to create CanvasView. Check that kendo.dataviz.canvas.js is loaded.");
                  }
              },
  
              getSize: function() {
                  return kendo.dimensions(this.element);
              },
  
              _resize: function() {
                  this.redraw();
              },
  
              _redraw: function(view) {
                  var that = this,
                      value = that._value,
                      baseUnit,
                      border = that.options.border || {},
                      padding = that.options.padding || 0,
                      borderWidth = border.width || 0,
                      quietZoneSize,
                      matrix,
                      size,
                      dataSize,
                      contentSize;
  
                  border.width = borderWidth;
  
                  if(!value){
                      return;
                  }
  
                  matrix = encodeData(value, that.options.errorCorrection, that.options.encoding);
                  size = that._getSize();
                  contentSize = size - 2 * (borderWidth + padding);
                  baseUnit = that._calculateBaseUnit(contentSize, matrix.length);
                  dataSize =  matrix.length * baseUnit;
                  
                  quietZoneSize = that._calculateQuietZone(dataSize, contentSize, borderWidth, padding);
  
                  view.children = [];
                  view.options.width = size;
                  view.options.height = size;
                  that._renderBackground(view, size, border);
                  that._renderMatrix(view, matrix, baseUnit, quietZoneSize);
              },
  
              _getSize: function(){
                  var that = this,
                      size;
                  if(that.options.size){
                     size = parseInt(that.options.size, 10);
                  }
                  else {
                      var element = that.element,
                          min = Math.min(element.width(), element.height());
  
                      if(min > 0){
                          size =  min;
                      }
                      else{
                          size = QRCodeDefaults.DEFAULT_SIZE;
                      }
                  }
  
                  return size;
              },
              _calculateBaseUnit: function(size, matrixSize){
                  var baseUnit = Math.floor(size/ matrixSize);
  
                  if(baseUnit < QRCodeDefaults.MIN_BASE_UNIT_SIZE){
                      throw new Error("Insufficient size.");
                  }
  
                  if(baseUnit * matrixSize >= size &&
                      baseUnit - 1 >= QRCodeDefaults.MIN_BASE_UNIT_SIZE){
                      baseUnit--;
                  }
  
                  return baseUnit;
              },
              _calculateQuietZone: function(dataSize, contentSize, border, padding){
                  return border + padding + (contentSize - dataSize) / 2;
              },
  
              _renderMatrix: function(view, matrix, baseUnit, quietZoneSize){
                  var that = this,
                      y,
                      x1,
                      box,
                      column,
                      elements = [];
  
                  for(var row = 0; row < matrix.length; row++){
                      y = quietZoneSize + row * baseUnit;
                      column = 0;
                      while(column < matrix.length){
                          while(matrix[row][column] === 0 && column < matrix.length){
                              column++;
                          }
                          if(column < matrix.length){
                              x1 = column;
                              while(matrix[row][column] == 1){
                                  column++;
                              }
                              box = new Box2D(
                                  round(quietZoneSize + x1 * baseUnit), round(y),
                                  round(quietZoneSize + column * baseUnit), round(y + baseUnit));
                              elements.push(box.points());
                          }
                      }
                  }
  
                  view.children.push(view.createMultiLine(elements, {
                          fill: that.options.color,
                          stroke: that.options.color, strokeWidth: 0,
                          align: false
                      }));
              },
  
              _renderBackground: function (view, size, border) {
                  var that = this;
                  view.children.push(view.createRect(Box2D(0,0, size, size).unpad(border.width / 2),
                      {
                          fill: that.options.background,
                          stroke: border.color,
                          strokeWidth: border.width,
                          align: false
                      }));
              },
  
              setOptions: function (options) {
                  var that = this;
                  options = options || {};
                  that.options = extend(that.options, options);
                  if (options.value !== undefined) {
                      that._value = that.options.value + "";
                  }
                  that.redraw();
              },
              value: function(value){
                  var that = this;
                  if (value === undefined) {
                      return that._value;
                  }
                  that._value = value + "";
                  that.redraw();
              },
              options: {
                  name: "QRCode",
                  renderAs: "svg",
                  encoding: "ISO_8859_1",
                  value: "",
                  errorCorrection: QRCodeDefaults.DEFAULT_ERROR_CORRECTION_LEVEL,
                  background: QRCodeDefaults.DEFAULT_BACKGROUND,
                  color: QRCodeDefaults.DEFAULT_DARK_MODULE_COLOR,
                  size: "",
                  padding: 0,
                  border: {
                      color: "",
                      width: 0
                  }
              }
          });
  
        dataviz.ui.plugin(QRCode);
  
        kendo.deepExtend(dataviz, {
              QRCode: QRCode,
              QRCodeDefaults: QRCodeDefaults,
              QRCodeFunctions: {
                  FreeCellVisitor: FreeCellVisitor,
                  fillData: fillData,
                  padDataString: padDataString,
                  generateErrorCodewords: generateErrorCodewords,
                  xorPolynomials: xorPolynomials,
                  getBlocks: getBlocks,
                  multiplyPolynomials: multiplyPolynomials,
                  chooseMode: chooseMode,
                  getModes: getModes,
                  getDataCodewordsCount: getDataCodewordsCount,
                  getVersion: getVersion,
                  getDataString: getDataString,
                  encodeFormatInformation: encodeFormatInformation,
                  encodeBCH: encodeBCH,
                  dividePolynomials: dividePolynomials,
                  initMatrices: initMatrices,
                  addFormatInformation: addFormatInformation,
                  encodeVersionInformation: encodeVersionInformation,
                  addVersionInformation: addVersionInformation,
                  addCentricPattern: addCentricPattern,
                  addFinderSeparator: addFinderSeparator,
                  addFinderPatterns: addFinderPatterns,
                  addAlignmentPatterns: addAlignmentPatterns,
                  addTimingFunctions: addTimingFunctions,
                  scoreMaskMatrixes: scoreMaskMatrixes,
                  encodeData: encodeData,
                  UTF8Encoder: UTF8Encoder
              },
              QRCodeFields: {
                  modes: modeInstances,
                  powersOfTwo: powersOfTwo,
                  powersOfTwoResult: powersOfTwoResult,
                  generatorPolynomials: generatorPolynomials
              }
        });
  
  })(window.kendo.jQuery);
  
  return window.kendo;
  
  }, typeof define == 'function' && define.amd ? define : function(_, f){ f(); });