text: //SainSmart ST7735 1.8" TFT LCD 128x160 pixel
  class SainSmartTFT18LCD {
    constructor() {
      this.keys = ['vcc', 'gnd', 'scl', 'sda', 'dc', 'res', 'cs'];
      this.required = ['scl', 'sda', 'dc', 'res', 'cs'];
  
      this.displayIoNames = {
        vcc: 'vcc',
        gnd: 'gnd',
        scl: 'scl',
        sda: 'sda',
        dc: 'dc',
        res: 'res',
        cs: 'cs',
      };
    }
  
    static info() {
      return {
        name: 'SainSmartTFT18LCD',
      };
    }
  
    wired(obniz) {
      this.debugprint = false;
      this.obniz = obniz;
      this.io_dc = obniz.getIO(this.params.dc);
      this.io_res = obniz.getIO(this.params.res);
      this.io_cs = obniz.getIO(this.params.cs);
  
      this.obniz.setVccGnd(this.params.vcc, this.params.gnd, '5v');
      this.params.frequency = 16 * 1000 * 1000; //16MHz
      this.params.mode = 'master';
      this.params.clk = this.params.scl;
      this.params.mosi = this.params.sda;
      this.params.drive = '3v';
      this.spi = this.obniz.getSpiWithConfig(this.params);
  
      this.io_dc.output(true);
      this.io_cs.output(false);
  
      this.width = ST7735_TFTWIDTH;
      this.height = ST7735_TFTHEIGHT;
  
      this.writeBuffer = []; //1024bytes bufferring
  
      this._setPresetColor();
      this.init();
    }
  
    print_debug(v) {
      if (this.debugprint) {
        console.log(
          'SainSmartTFT18LCD: ' + Array.prototype.slice.call(arguments).join('')
        );
      }
    }
    _deadSleep(waitMsec) {
      let startMsec = new Date();
      while (new Date() - startMsec < waitMsec);
    }
    _reset() {
      this.io_res.output(false);
      this._deadSleep(10);
      this.io_res.output(true);
      this._deadSleep(10);
    }
  
    writeCommand(cmd) {
      this.io_dc.output(false);
      this.io_cs.output(false);
      this.spi.write([cmd]);
      this.io_cs.output(true);
    }
    writeData(data) {
      this.io_dc.output(true);
      this.io_cs.output(false);
      this.spi.write(data);
      this.io_cs.output(true);
    }
    write(cmd, data) {
      if (data.length == 0) return;
      this.writeCommand(cmd);
      this.writeData(data);
    }
    async asyncwait() {
      return await this.spi.writeWait([0x00]);
    }
    _writeFlush() {
      while (this.writeBuffer.length > 0) {
        if (this.writeBuffer.length > 1024) {
          let data = this.writeBuffer.slice(0, 1024);
          this.writeData(data);
          this.writeBuffer.splice(0, 1024);
        } else {
          if (this.writeBuffer.length > 0) this.writeData(this.writeBuffer);
          this.writeBuffer = [];
        }
      }
    }
    _writeBuffer(data) {
      if (data && data.length > 0) {
        this.writeBuffer = this.writeBuffer.concat(data);
      } else {
        this._writeFlush();
      }
    }
  
    color16(r, g, b) {
      //  1st byte  (r & 0xF8 | g >> 5)
      //  2nd byte  (g & 0xFC << 3 | b >> 3)
      return ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
    }
  
    _initG() {
      // initialize for Green Tab
      this.writeCommand(ST7735_SLPOUT); //Sleep out & booster on
      this.obniz.wait(120);
      this.write(ST7735_FRMCTR1, [0x01, 0x2c, 0x2d]);
      this.write(ST7735_FRMCTR2, [0x01, 0x2c, 0x2d]);
      this.write(ST7735_FRMCTR3, [0x01, 0x2c, 0x2d, 0x01, 0x2c, 0x2d]);
      this.write(ST7735_INVCTR, [0x07]);
      this.write(ST7735_PWCTR1, [0xa2, 0x02, 0x84]);
      this.write(ST7735_PWCTR2, [0xc5]);
      this.write(ST7735_PWCTR3, [0x0a, 0x00]);
      this.write(ST7735_PWCTR4, [0x8a, 0x2a]);
      this.write(ST7735_PWCTR5, [0x8a, 0xee]);
      this.write(ST7735_VMCTR1, [0x0e]);
      this.write(ST7735_GMCTRP1, [
        0x02,
        0x1c,
        0x07,
        0x12,
        0x37,
        0x32,
        0x29,
        0x2d,
        0x29,
        0x25,
        0x2b,
        0x39,
        0x00,
        0x01,
        0x03,
        0x10,
      ]);
      this.write(ST7735_GMCTRN1, [
        0x03,
        0x1d,
        0x07,
        0x06,
        0x2e,
        0x2c,
        0x29,
        0x2d,
        0x2e,
        0x2e,
        0x37,
        0x3f,
        0x00,
        0x00,
        0x02,
        0x10,
      ]);
      this.write(ST7735_COLMOD, [ST7735_16bit]); // color format: 16bit/pixel
    }
  
    init() {
      this._reset();
      this._initG();
      this.setDisplayOn();
      this.setRotation(0);
    }
  
    setDisplayOn() {
      this.writeCommand(ST7735_DISPON);
    }
    setDisplayOff() {
      this.writeCommand(ST7735_DISPOFF);
    }
    setDisplay(on) {
      if (on == true) this.setDisplayOn();
      else this.setDisplayOff();
    }
  
    setInversionOn() {
      this.writeCommand(ST7735_INVON);
    }
    setInversionOff() {
      this.writeCommand(ST7735_INVOFF);
    }
    setInversion(inversion) {
      if (inversion == true) this.setInversionOn();
      else this.setInversionOff();
    }
  
    setRotation(m) {
      const MADCTL_MY = 0x80;
      const MADCTL_MX = 0x40;
      const MADCTL_MV = 0x20;
      // const MADCTL_ML = 0x10;
      const MADCTL_RGB = 0x00; //always RGB, never BGR
      // const MADCTL_MH = 0x04;
  
      let data;
      let rotation = m % 4; // can't be higher than 3
      switch (rotation) {
        case 0:
          data = [MADCTL_MX | MADCTL_MY | MADCTL_RGB];
          this.width = ST7735_TFTWIDTH;
          this.height = ST7735_TFTHEIGHT;
          break;
        case 1:
          data = [MADCTL_MY | MADCTL_MV | MADCTL_RGB];
          this.width = ST7735_TFTHEIGHT;
          this.height = ST7735_TFTWIDTH;
          break;
        case 2:
          data = [MADCTL_RGB];
          this.width = ST7735_TFTWIDTH;
          this.height = ST7735_TFTHEIGHT;
          break;
        case 3:
          data = [MADCTL_MX | MADCTL_MV | MADCTL_RGB];
          this.width = ST7735_TFTHEIGHT;
          this.height = ST7735_TFTWIDTH;
          break;
      }
      this.write(ST7735_MADCTL, data);
      this.setAddrWindow(0, 0, this.width - 1, this.height - 1);
    }
  
    setAddrWindow(x0, y0, x1, y1) {
      this.print_debug(
        `setAddrWindow: (x0: ${x0}, y0: ${y0}) - (x1: ${x1}, y1: ${y1})`
      );
  
      if (x0 < 0) x0 = 0;
      if (y0 < 0) y0 = 0;
      if (x1 < 0) x1 = 0;
      if (y1 < 0) y1 = 0;
  
      // column addr set
      this.write(ST7735_CASET, [0x00, x0, 0x00, x1]); // XSTART-XEND
      // row addr set
      this.write(ST7735_RASET, [0x00, y0, 0x00, y1]); // YSTART-YEND
      // write to RAM
      this.writeCommand(ST7735_RAMWR);
      this.writeBuffer = [];
    }
  
    //__swap(a, b) { let t = a; a = b; b = t; }
  
    fillScreen(color) {
      this.fillRect(0, 0, this.width, this.height, color);
    }
    fillRect(x, y, w, h, color) {
      if (x >= this.width || y >= this.height) return;
      if (x + w - 1 >= this.width) w = this.width - x;
      if (y + h - 1 >= this.height) h = this.height - y;
  
      this.setAddrWindow(x, y, x + w - 1, y + h - 1);
  
      let hi = color >> 8,
        lo = color & 0xff;
      let data = [];
  
      for (y = h; y > 0; y--) {
        for (x = w; x > 0; x--) {
          data.push(hi);
          data.push(lo);
        }
      }
      this._writeBuffer(data);
      this._writeBuffer(); //for flush
    }
    drawRect(x, y, w, h, color) {
      this.drawHLine(x, y, w, color);
      this.drawHLine(x, y + h - 1, w, color);
      this.drawVLine(x, y, h, color);
      this.drawVLine(x + w - 1, y, h, color);
    }
    drawCircle(x0, y0, r, color) {
      let f = 1 - r;
      let ddF_x = 1;
      let ddF_y = -2 * r;
      let x = 0;
      let y = r;
  
      this.drawPixel(x0, y0 + r, color);
      this.drawPixel(x0, y0 - r, color);
      this.drawPixel(x0 + r, y0, color);
      this.drawPixel(x0 - r, y0, color);
  
      while (x < y) {
        if (f >= 0) {
          y--;
          ddF_y += 2;
          f += ddF_y;
        }
        x++;
        ddF_x += 2;
        f += ddF_x;
  
        this.drawPixel(x0 + x, y0 + y, color);
        this.drawPixel(x0 - x, y0 + y, color);
        this.drawPixel(x0 + x, y0 - y, color);
        this.drawPixel(x0 - x, y0 - y, color);
        this.drawPixel(x0 + y, y0 + x, color);
        this.drawPixel(x0 - y, y0 + x, color);
        this.drawPixel(x0 + y, y0 - x, color);
        this.drawPixel(x0 - y, y0 - x, color);
      }
    }
    _drawCircleHelper(x0, y0, r, cornername, color) {
      let f = 1 - r;
      let ddF_x = 1;
      let ddF_y = -2 * r;
      let x = 0;
      let y = r;
  
      while (x < y) {
        if (f >= 0) {
          y--;
          ddF_y += 2;
          f += ddF_y;
        }
        x++;
        ddF_x += 2;
        f += ddF_x;
        if (cornername & 0x4) {
          this.drawPixel(x0 + x, y0 + y, color);
          this.drawPixel(x0 + y, y0 + x, color);
        }
        if (cornername & 0x2) {
          this.drawPixel(x0 + x, y0 - y, color);
          this.drawPixel(x0 + y, y0 - x, color);
        }
        if (cornername & 0x8) {
          this.drawPixel(x0 - y, y0 + x, color);
          this.drawPixel(x0 - x, y0 + y, color);
        }
        if (cornername & 0x1) {
          this.drawPixel(x0 - y, y0 - x, color);
          this.drawPixel(x0 - x, y0 - y, color);
        }
      }
    }
    fillCircle(x0, y0, r, color) {
      this.drawVLine(x0, y0 - r, 2 * r + 1, color);
      this._fillCircleHelper(x0, y0, r, 3, 0, color);
    }
    _fillCircleHelper(x0, y0, r, cornername, delta, color) {
      let f = 1 - r;
      let ddF_x = 1;
      let ddF_y = -2 * r;
      let x = 0;
      let y = r;
  
      while (x < y) {
        if (f >= 0) {
          y--;
          ddF_y += 2;
          f += ddF_y;
        }
        x++;
        ddF_x += 2;
        f += ddF_x;
  
        if (cornername & 0x1) {
          this.drawVLine(x0 + x, y0 - y, 2 * y + 1 + delta, color);
          this.drawVLine(x0 + y, y0 - x, 2 * x + 1 + delta, color);
        }
        if (cornername & 0x2) {
          this.drawVLine(x0 - x, y0 - y, 2 * y + 1 + delta, color);
          this.drawVLine(x0 - y, y0 - x, 2 * x + 1 + delta, color);
        }
      }
    }
    drawRoundRect(x, y, w, h, r, color) {
      this.drawHLine(x + r, y, w - 2 * r, color); // Top
      this.drawHLine(x + r, y + h - 1, w - 2 * r, color); // Bottom
      this.drawVLine(x, y + r, h - 2 * r, color); // Left
      this.drawVLine(x + w - 1, y + r, h - 2 * r, color); // Right
  
      this._drawCircleHelper(x + r, y + r, r, 1, color);
      this._drawCircleHelper(x + w - r - 1, y + r, r, 2, color);
      this._drawCircleHelper(x + w - r - 1, y + h - r - 1, r, 4, color);
      this._drawCircleHelper(x + r, y + h - r - 1, r, 8, color);
    }
    fillRoundRect(x, y, w, h, r, color) {
      this.fillRect(x + r, y, w - 2 * r, h, color);
  
      this._fillCircleHelper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1, color);
      this._fillCircleHelper(x + r, y + r, r, 2, h - 2 * r - 1, color);
    }
    drawTriangle(x0, y0, x1, y1, x2, y2, color) {
      this.drawLine(x0, y0, x1, y1, color);
      this.drawLine(x1, y1, x2, y2, color);
      this.drawLine(x2, y2, x0, y0, color);
    }
    fillTriangle(x0, y0, x1, y1, x2, y2, color) {
      let a, b, y, last;
  
      // Sort coordinates by Y order (y2 >= y1 >= y0)
      if (y0 > y1) {
        y1 = [y0, (y0 = y1)][0]; //this._swap(y0, y1);
        x1 = [x0, (x0 = x1)][0]; //this._swap(x0, x1);
      }
      if (y1 > y2) {
        y2 = [y1, (y1 = y2)][0]; //this._swap(y2, y1);
        x2 = [x1, (x1 = x2)][0]; //this._swap(x2, x1);
      }
      if (y0 > y1) {
        y1 = [y0, (y0 = y1)][0]; //this._swap(y0, y1);
        x1 = [x0, (x0 = x1)][0]; //this._swap(x0, x1);
      }
  
      if (y0 == y2) {
        // Handle awkward all-on-same-line case as its own thing
        a = b = x0;
        if (x1 < a) a = x1;
        else if (x1 > b) b = x1;
        if (x2 < a) a = x2;
        else if (x2 > b) b = x2;
        this.drawHLine(a, y0, b - a + 1, color);
        return;
      }
  
      let dx01 = x1 - x0,
        dy01 = y1 - y0,
        dx02 = x2 - x0,
        dy02 = y2 - y0,
        dx12 = x2 - x1,
        dy12 = y2 - y1,
        sa = 0,
        sb = 0;
  
      if (y1 == y2) last = y1;
      // include y1 scanline
      else last = y1 - 1; // skip it
  
      for (y = y0; y <= last; y++) {
        a = x0 + Math.floor(sa / dy01);
        b = x0 + Math.floor(sb / dy02);
        sa += dx01;
        sb += dx02;
        if (a > b) b = [a, (a = b)][0]; //this._swap(a,b);
        this.drawHLine(a, y, b - a + 1, color);
      }
  
      sa = dx12 * (y - y1);
      sb = dx02 * (y - y0);
      for (; y <= y2; y++) {
        a = x1 + Math.floor(sa / dy12);
        b = x0 + Math.floor(sb / dy02);
        sa += dx12;
        sb += dx02;
        if (a > b) b = [a, (a = b)][0]; //this._swap(a,b);
        this.drawHLine(a, y, b - a + 1, color);
      }
    }
    drawVLine(x, y, h, color) {
      if (x >= this.width || y >= this.height) return;
      if (y + h - 1 >= this.height) h = this.height - y;
  
      this.setAddrWindow(x, y, x, y + h - 1);
  
      let hi = color >> 8,
        lo = color & 0xff;
      let data = [];
      while (h--) {
        data.push(hi);
        data.push(lo);
      }
      this.writeData(data);
    }
    drawHLine(x, y, w, color) {
      if (x >= this.width || y >= this.height) return;
      if (x + w - 1 >= this.width) w = this.width - x;
  
      this.setAddrWindow(x, y, x + w - 1, y);
  
      let hi = color >> 8,
        lo = color & 0xff;
      let data = [];
      while (w--) {
        data.push(hi);
        data.push(lo);
      }
      this.writeData(data);
    }
    drawLine(x0, y0, x1, y1, color) {
      let step = Math.abs(y1 - y0) > Math.abs(x1 - x0);
      if (step) {
        y0 = [x0, (x0 = y0)][0]; //this._swap(x0, y0);
        y1 = [x1, (x1 = y1)][0]; //this._swap(x1, y1);
      }
      if (x0 > x1) {
        x1 = [x0, (x0 = x1)][0]; //this._swap(x0, x1);
        y1 = [y0, (y0 = y1)][0]; //this._swap(y0, y1);
      }
  
      let dx = x1 - x0;
      let dy = Math.abs(y1 - y0);
  
      let err = dx / 2;
      let ystep = y0 < y1 ? 1 : -1;
  
      for (; x0 <= x1; x0++) {
        if (step) {
          this.drawPixel(y0, x0, color);
        } else {
          this.drawPixel(x0, y0, color);
        }
        err -= dy;
        if (err < 0) {
          y0 += ystep;
          err += dx;
        }
      }
    }
    drawPixel(x, y, color) {
      if (x < 0 || x >= this.width || y < 0 || y >= this.height) return;
  
      this.setAddrWindow(x, y, x + 1, y + 1);
      this.writeData([color >> 8, color & 0xff]);
    }
    drawChar(x, y, ch, color, bg, size) {
      //  bg = bg || color;
      size = size || 1;
      if (
        x >= this.width || // Clip right
        y >= this.height || // Clip bottom
        x + 6 * size - 1 < 0 || // Clip left
        y + 8 * size - 1 < 0
      )
        // Clip top
        return;
  
      if (color != bg) {
        this.drawChar2(x, y, ch, color, bg, size);
        return;
      }
  
      let c = ch.charCodeAt(0);
      for (let i = 0; i < 6; i++) {
        let line = i == 5 ? 0 : font[c * 5 + i];
        for (let j = 0; j < 8; j++) {
          if (line & 0x1) {
            if (size == 1)
              // default size
              this.drawPixel(x + i, y + j, color);
            else {
              // big size
              this.fillRect(x + i * size, y + j * size, size, size, color);
            }
          } else if (bg != color) {
            if (size == 1)
              // default size
              this.drawPixel(x + i, y + j, bg);
            else {
              // big size
              this.fillRect(x + i * size, y + j * size, size, size, bg);
            }
          }
          line >>= 1;
        }
      }
    }
    drawChar2(x, y, ch, color, bg, size) {
      //  bg = bg || color;
      size = size || 1;
      if (
        x >= this.width || // Clip right
        y >= this.height || // Clip bottom
        x + 6 * size - 1 < 0 || // Clip left
        y + 8 * size - 1 < 0 // Clip top
      )
        return;
  
      let pixels = new Array(6 * 8 * size * size);
      let c = ch.charCodeAt(0);
      for (let i = 0; i < 6; i++) {
        let line = i == 5 ? 0 : font[c * 5 + i];
        for (let j = 0; j < 8; j++) {
          let cl = line & 0x1 ? color : bg;
          for (let w = 0; w < size; w++) {
            for (let h = 0; h < size; h++) {
              pixels[
                i * (1 * size) + w + (j * (6 * size * size) + h * (6 * size))
              ] = cl;
            }
          }
          line >>= 1;
        }
      }
      this.rawBound16(x, y, 6 * size, 8 * size, pixels);
    }
    rawBound16(x, y, width, height, pixels) {
      let rgb = [];
      pixels.forEach(function(v) {
        rgb.push((v & 0xff00) >> 8);
        rgb.push(v & 0xff);
      });
      this.setAddrWindow(x, y, x + width - 1, y + height - 1);
      this._writeBuffer(rgb);
      this._writeBuffer(); //for flush
    }
    drawString(x, y, str, color, bg, size, wrap) {
      //  bg = bg || color;
      size = size || 1;
      //  wrap = wrap || true;
      for (let n = 0; n < str.length; n++) {
        let c = str.charAt(n);
        if (c == '\n') {
          y += size * 8;
          x = 0;
        } else if (c == '\r') {
          // skip em
        } else {
          this.drawChar(x, y, c, color, bg, size);
          x += size * 6;
          if (wrap && x > this.width - size * 6) {
            y += size * 8;
            x = 0;
          }
        }
      }
      return [x, y];
    }
    drawContextBound(context, x0, y0, width, height, x1, y1, gray) {
      x0 = x0 || 0;
      y0 = y0 || 0;
      width = width || context.canvas.clientWidth;
      height = height || context.canvas.clientHeight;
      x1 = x1 || 0;
      y1 = y1 || 0;
      gray = gray || false;
      this.write(ST7735_COLMOD, [ST7735_18bit]); //18bit/pixel
      let imageData = context.getImageData(x0, y0, width, height).data;
      let rgb = [];
      for (let n = 0; n < imageData.length; n += 4) {
        let r = imageData[n + 0];
        let g = imageData[n + 1];
        let b = imageData[n + 2];
        if (!gray) {
          rgb.push(r);
          rgb.push(g);
          rgb.push(b);
        } else {
          let gs = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
          rgb.push(gs);
          rgb.push(gs);
          rgb.push(gs);
        }
      }
      this.write(ST7735_COLMOD, [ST7735_18bit]); //18bit/pixel
      this.setAddrWindow(x1, y1, x1 + width - 1, y1 + height - 1);
      this._writeBuffer(rgb);
      this._writeBuffer(); //for flush
      this.write(ST7735_COLMOD, [ST7735_16bit]); //16bit/pixel
    }
    drawContext(context, gray) {
      gray = gray || false;
      this.drawContextBound(context, 0, 0, this.width, this.height, 0, 0, gray);
    }
    rawBound(x, y, width, height, pixels) {
      let rgb = [];
      pixels.forEach(function(v) {
        rgb.push((v & 0xff0000) >> 16);
        rgb.push((v & 0xff00) >> 8);
        rgb.push(v & 0xff);
      });
      this.write(ST7735_COLMOD, [ST7735_18bit]); //18bit/pixel
      this.setAddrWindow(x, y, x + width - 1, y + height - 1);
      this._writeBuffer(rgb);
      this._writeBuffer(); //for flush
      this.write(ST7735_COLMOD, [ST7735_16bit]); //16bit/pixel
    }
    raw(pixels) {
      this.raw(0, 0, this.width, this.height, pixels);
    }
  
    _setPresetColor() {
      this.color = {
        AliceBlue: 0xf7df,
        AntiqueWhite: 0xff5a,
        Aqua: 0x07ff,
        Aquamarine: 0x7ffa,
        Azure: 0xf7ff,
        Beige: 0xf7bb,
        Bisque: 0xff38,
        Black: 0x0000,
        BlanchedAlmond: 0xff59,
        Blue: 0x001f,
        BlueViolet: 0x895c,
        Brown: 0xa145,
        BurlyWood: 0xddd0,
        CadetBlue: 0x5cf4,
        Chartreuse: 0x7fe0,
        Chocolate: 0xd343,
        Coral: 0xfbea,
        CornflowerBlue: 0x64bd,
        Cornsilk: 0xffdb,
        Crimson: 0xd8a7,
        Cyan: 0x07ff,
        DarkBlue: 0x0011,
        DarkCyan: 0x0451,
        DarkGoldenRod: 0xbc21,
        DarkGray: 0xad55,
        DarkGreen: 0x0320,
        DarkKhaki: 0xbdad,
        DarkMagenta: 0x8811,
        DarkOliveGreen: 0x5345,
        DarkOrange: 0xfc60,
        DarkOrchid: 0x9999,
        DarkRed: 0x8800,
        DarkSalmon: 0xecaf,
        DarkSeaGreen: 0x8df1,
        DarkSlateBlue: 0x49f1,
        DarkSlateGray: 0x2a69,
        DarkTurquoise: 0x067a,
        DarkViolet: 0x901a,
        DeepPink: 0xf8b2,
        DeepSkyBlue: 0x05ff,
        DimGray: 0x6b4d,
        DodgerBlue: 0x1c9f,
        FireBrick: 0xb104,
        FloralWhite: 0xffde,
        ForestGreen: 0x2444,
        Fuchsia: 0xf81f,
        Gainsboro: 0xdefb,
        GhostWhite: 0xffdf,
        Gold: 0xfea0,
        GoldenRod: 0xdd24,
        Gray: 0x8410,
        Green: 0x0400,
        GreenYellow: 0xafe5,
        HoneyDew: 0xf7fe,
        HotPink: 0xfb56,
        IndianRed: 0xcaeb,
        Indigo: 0x4810,
        Ivory: 0xfffe,
        Khaki: 0xf731,
        Lavender: 0xe73f,
        LavenderBlush: 0xff9e,
        LawnGreen: 0x7fe0,
        LemonChiffon: 0xffd9,
        LightBlue: 0xaedc,
        LightCoral: 0xf410,
        LightCyan: 0xe7ff,
        LightGoldenRodYellow: 0xffda,
        LightGray: 0xd69a,
        LightGreen: 0x9772,
        LightPink: 0xfdb8,
        LightSalmon: 0xfd0f,
        LightSeaGreen: 0x2595,
        LightSkyBlue: 0x867f,
        LightSlateGray: 0x7453,
        LightSteelBlue: 0xb63b,
        LightYellow: 0xfffc,
        Lime: 0x07e0,
        LimeGreen: 0x3666,
        Linen: 0xff9c,
        Magenta: 0xf81f,
        Maroon: 0x8000,
        MediumAquaMarine: 0x6675,
        MediumBlue: 0x0019,
        MediumOrchid: 0xbaba,
        MediumPurple: 0x939b,
        MediumSeaGreen: 0x3d8e,
        MediumSlateBlue: 0x7b5d,
        MediumSpringGreen: 0x07d3,
        MediumTurquoise: 0x4e99,
        MediumVioletRed: 0xc0b0,
        MidnightBlue: 0x18ce,
        MintCream: 0xf7ff,
        MistyRose: 0xff3c,
        Moccasin: 0xff36,
        NavajoWhite: 0xfef5,
        Navy: 0x0010,
        OldLace: 0xffbc,
        Olive: 0x8400,
        OliveDrab: 0x6c64,
        Orange: 0xfd20,
        OrangeRed: 0xfa20,
        Orchid: 0xdb9a,
        PaleGoldenRod: 0xef55,
        PaleGreen: 0x9fd3,
        PaleTurquoise: 0xaf7d,
        PaleVioletRed: 0xdb92,
        PapayaWhip: 0xff7a,
        PeachPuff: 0xfed7,
        Peru: 0xcc27,
        Pink: 0xfe19,
        Plum: 0xdd1b,
        PowderBlue: 0xb71c,
        Purple: 0x8010,
        RebeccaPurple: 0x6193,
        Red: 0xf800,
        RosyBrown: 0xbc71,
        RoyalBlue: 0x435c,
        SaddleBrown: 0x8a22,
        Salmon: 0xfc0e,
        SandyBrown: 0xf52c,
        SeaGreen: 0x2c4a,
        SeaShell: 0xffbd,
        Sienna: 0xa285,
        Silver: 0xc618,
        SkyBlue: 0x867d,
        SlateBlue: 0x6ad9,
        SlateGray: 0x7412,
        Snow: 0xffdf,
        SpringGreen: 0x07ef,
        SteelBlue: 0x4416,
        Tan: 0xd5b1,
        Teal: 0x0410,
        Thistle: 0xddfb,
        Tomato: 0xfb08,
        Turquoise: 0x471a,
        Violet: 0xec1d,
        Wheat: 0xf6f6,
        White: 0xffff,
        WhiteSmoke: 0xf7be,
        Yellow: 0xffe0,
        YellowGreen: 0x9e66,
      };
    }
  }
  
  if (typeof module === 'object') {
    module.exports = SainSmartTFT18LCD;
  }
  
  //----------------------------------------------------------
  
  // commands
  // const INITR_GREENTAB = 0x0;
  // const INITR_REDTAB = 0x1;
  // const INITR_BLACKTAB = 0x2;
  
  const ST7735_TFTWIDTH = 128;
  const ST7735_TFTHEIGHT = 160;
  
  // const ST7735_NOP = 0x00;
  // const ST7735_SWRESET = 0x01;
  // const ST7735_RDDID = 0x04;
  // const ST7735_RDDST = 0x09;
  // const ST7735_RDDPM = 0x0a;
  
  // const ST7735_SLPIN = 0x10;
  const ST7735_SLPOUT = 0x11;
  // const ST7735_PTLON = 0x12;
  // const ST7735_NORON = 0x13;
  
  const ST7735_INVOFF = 0x20;
  const ST7735_INVON = 0x21;
  const ST7735_DISPOFF = 0x28;
  const ST7735_DISPON = 0x29;
  const ST7735_CASET = 0x2a;
  const ST7735_RASET = 0x2b;
  const ST7735_RAMWR = 0x2c;
  // const ST7735_RAMRD = 0x2e;
  
  // const ST7735_PTLAR = 0x30;
  const ST7735_COLMOD = 0x3a;
  const ST7735_MADCTL = 0x36;
  
  const ST7735_FRMCTR1 = 0xb1;
  const ST7735_FRMCTR2 = 0xb2;
  const ST7735_FRMCTR3 = 0xb3;
  const ST7735_INVCTR = 0xb4;
  // const ST7735_DISSET5 = 0xb6;
  
  const ST7735_PWCTR1 = 0xc0;
  const ST7735_PWCTR2 = 0xc1;
  const ST7735_PWCTR3 = 0xc2;
  const ST7735_PWCTR4 = 0xc3;
  const ST7735_PWCTR5 = 0xc4;
  const ST7735_VMCTR1 = 0xc5;
  
  // const ST7735_RDID1 = 0xda;
  // const ST7735_RDID2 = 0xdb;
  // const ST7735_RDID3 = 0xdc;
  // const ST7735_RDID4 = 0xdd;
  
  // const ST7735_PWCTR6 = 0xfc;
  
  const ST7735_GMCTRP1 = 0xe0;
  const ST7735_GMCTRN1 = 0xe1;
  
  // Color definitions
  // const ST7735_BLACK = 0x0000;
  // const ST7735_BLUE = 0x001f;
  // const ST7735_RED = 0xf800;
  // const ST7735_GREEN = 0x07e0;
  // const ST7735_CYAN = 0x07ff;
  // const ST7735_MAGENTA = 0xf81f;
  // const ST7735_YELLOW = 0xffe0;
  // const ST7735_WHITE = 0xffff;
  
  const ST7735_18bit = 0x06; // 18bit/pixel
  const ST7735_16bit = 0x05; // 16bit/pixel
  
  // standard ascii 5x7 font
  const font = [
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x3e,
    0x5b,
    0x4f,
    0x5b,
    0x3e,
    0x3e,
    0x6b,
    0x4f,
    0x6b,
    0x3e,
    0x1c,
    0x3e,
    0x7c,
    0x3e,
    0x1c,
    0x18,
    0x3c,
    0x7e,
    0x3c,
    0x18,
    0x1c,
    0x57,
    0x7d,
    0x57,
    0x1c,
    0x1c,
    0x5e,
    0x7f,
    0x5e,
    0x1c,
    0x00,
    0x18,
    0x3c,
    0x18,
    0x00,
    0xff,
    0xe7,
    0xc3,
    0xe7,
    0xff,
    0x00,
    0x18,
    0x24,
    0x18,
    0x00,
    0xff,
    0xe7,
    0xdb,
    0xe7,
    0xff,
    0x30,
    0x48,
    0x3a,
    0x06,
    0x0e,
    0x26,
    0x29,
    0x79,
    0x29,
    0x26,
    0x40,
    0x7f,
    0x05,
    0x05,
    0x07,
    0x40,
    0x7f,
    0x05,
    0x25,
    0x3f,
    0x5a,
    0x3c,
    0xe7,
    0x3c,
    0x5a,
    0x7f,
    0x3e,
    0x1c,
    0x1c,
    0x08,
    0x08,
    0x1c,
    0x1c,
    0x3e,
    0x7f,
    0x14,
    0x22,
    0x7f,
    0x22,
    0x14,
    0x5f,
    0x5f,
    0x00,
    0x5f,
    0x5f,
    0x06,
    0x09,
    0x7f,
    0x01,
    0x7f,
    0x00,
    0x66,
    0x89,
    0x95,
    0x6a,
    0x60,
    0x60,
    0x60,
    0x60,
    0x60,
    0x94,
    0xa2,
    0xff,
    0xa2,
    0x94,
    0x08,
    0x04,
    0x7e,
    0x04,
    0x08,
    0x10,
    0x20,
    0x7e,
    0x20,
    0x10,
    0x08,
    0x08,
    0x2a,
    0x1c,
    0x08,
    0x08,
    0x1c,
    0x2a,
    0x08,
    0x08,
    0x1e,
    0x10,
    0x10,
    0x10,
    0x10,
    0x0c,
    0x1e,
    0x0c,
    0x1e,
    0x0c,
    0x30,
    0x38,
    0x3e,
    0x38,
    0x30,
    0x06,
    0x0e,
    0x3e,
    0x0e,
    0x06,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x5f,
    0x00,
    0x00,
    0x00,
    0x07,
    0x00,
    0x07,
    0x00,
    0x14,
    0x7f,
    0x14,
    0x7f,
    0x14,
    0x24,
    0x2a,
    0x7f,
    0x2a,
    0x12,
    0x23,
    0x13,
    0x08,
    0x64,
    0x62,
    0x36,
    0x49,
    0x56,
    0x20,
    0x50,
    0x00,
    0x08,
    0x07,
    0x03,
    0x00,
    0x00,
    0x1c,
    0x22,
    0x41,
    0x00,
    0x00,
    0x41,
    0x22,
    0x1c,
    0x00,
    0x2a,
    0x1c,
    0x7f,
    0x1c,
    0x2a,
    0x08,
    0x08,
    0x3e,
    0x08,
    0x08,
    0x00,
    0x80,
    0x70,
    0x30,
    0x00,
    0x08,
    0x08,
    0x08,
    0x08,
    0x08,
    0x00,
    0x00,
    0x60,
    0x60,
    0x00,
    0x20,
    0x10,
    0x08,
    0x04,
    0x02,
    0x3e,
    0x51,
    0x49,
    0x45,
    0x3e,
    0x00,
    0x42,
    0x7f,
    0x40,
    0x00,
    0x72,
    0x49,
    0x49,
    0x49,
    0x46,
    0x21,
    0x41,
    0x49,
    0x4d,
    0x33,
    0x18,
    0x14,
    0x12,
    0x7f,
    0x10,
    0x27,
    0x45,
    0x45,
    0x45,
    0x39,
    0x3c,
    0x4a,
    0x49,
    0x49,
    0x31,
    0x41,
    0x21,
    0x11,
    0x09,
    0x07,
    0x36,
    0x49,
    0x49,
    0x49,
    0x36,
    0x46,
    0x49,
    0x49,
    0x29,
    0x1e,
    0x00,
    0x00,
    0x14,
    0x00,
    0x00,
    0x00,
    0x40,
    0x34,
    0x00,
    0x00,
    0x00,
    0x08,
    0x14,
    0x22,
    0x41,
    0x14,
    0x14,
    0x14,
    0x14,
    0x14,
    0x00,
    0x41,
    0x22,
    0x14,
    0x08,
    0x02,
    0x01,
    0x59,
    0x09,
    0x06,
    0x3e,
    0x41,
    0x5d,
    0x59,
    0x4e,
    0x7c,
    0x12,
    0x11,
    0x12,
    0x7c,
    0x7f,
    0x49,
    0x49,
    0x49,
    0x36,
    0x3e,
    0x41,
    0x41,
    0x41,
    0x22,
    0x7f,
    0x41,
    0x41,
    0x41,
    0x3e,
    0x7f,
    0x49,
    0x49,
    0x49,
    0x41,
    0x7f,
    0x09,
    0x09,
    0x09,
    0x01,
    0x3e,
    0x41,
    0x41,
    0x51,
    0x73,
    0x7f,
    0x08,
    0x08,
    0x08,
    0x7f,
    0x00,
    0x41,
    0x7f,
    0x41,
    0x00,
    0x20,
    0x40,
    0x41,
    0x3f,
    0x01,
    0x7f,
    0x08,
    0x14,
    0x22,
    0x41,
    0x7f,
    0x40,
    0x40,
    0x40,
    0x40,
    0x7f,
    0x02,
    0x1c,
    0x02,
    0x7f,
    0x7f,
    0x04,
    0x08,
    0x10,
    0x7f,
    0x3e,
    0x41,
    0x41,
    0x41,
    0x3e,
    0x7f,
    0x09,
    0x09,
    0x09,
    0x06,
    0x3e,
    0x41,
    0x51,
    0x21,
    0x5e,
    0x7f,
    0x09,
    0x19,
    0x29,
    0x46,
    0x26,
    0x49,
    0x49,
    0x49,
    0x32,
    0x03,
    0x01,
    0x7f,
    0x01,
    0x03,
    0x3f,
    0x40,
    0x40,
    0x40,
    0x3f,
    0x1f,
    0x20,
    0x40,
    0x20,
    0x1f,
    0x3f,
    0x40,
    0x38,
    0x40,
    0x3f,
    0x63,
    0x14,
    0x08,
    0x14,
    0x63,
    0x03,
    0x04,
    0x78,
    0x04,
    0x03,
    0x61,
    0x59,
    0x49,
    0x4d,
    0x43,
    0x00,
    0x7f,
    0x41,
    0x41,
    0x41,
    0x02,
    0x04,
    0x08,
    0x10,
    0x20,
    0x00,
    0x41,
    0x41,
    0x41,
    0x7f,
    0x04,
    0x02,
    0x01,
    0x02,
    0x04,
    0x40,
    0x40,
    0x40,
    0x40,
    0x40,
    0x00,
    0x03,
    0x07,
    0x08,
    0x00,
    0x20,
    0x54,
    0x54,
    0x78,
    0x40,
    0x7f,
    0x28,
    0x44,
    0x44,
    0x38,
    0x38,
    0x44,
    0x44,
    0x44,
    0x28,
    0x38,
    0x44,
    0x44,
    0x28,
    0x7f,
    0x38,
    0x54,
    0x54,
    0x54,
    0x18,
    0x00,
    0x08,
    0x7e,
    0x09,
    0x02,
    0x18,
    0xa4,
    0xa4,
    0x9c,
    0x78,
    0x7f,
    0x08,
    0x04,
    0x04,
    0x78,
    0x00,
    0x44,
    0x7d,
    0x40,
    0x00,
    0x20,
    0x40,
    0x40,
    0x3d,
    0x00,
    0x7f,
    0x10,
    0x28,
    0x44,
    0x00,
    0x00,
    0x41,
    0x7f,
    0x40,
    0x00,
    0x7c,
    0x04,
    0x78,
    0x04,
    0x78,
    0x7c,
    0x08,
    0x04,
    0x04,
    0x78,
    0x38,
    0x44,
    0x44,
    0x44,
    0x38,
    0xfc,
    0x18,
    0x24,
    0x24,
    0x18,
    0x18,
    0x24,
    0x24,
    0x18,
    0xfc,
    0x7c,
    0x08,
    0x04,
    0x04,
    0x08,
    0x48,
    0x54,
    0x54,
    0x54,
    0x24,
    0x04,
    0x04,
    0x3f,
    0x44,
    0x24,
    0x3c,
    0x40,
    0x40,
    0x20,
    0x7c,
    0x1c,
    0x20,
    0x40,
    0x20,
    0x1c,
    0x3c,
    0x40,
    0x30,
    0x40,
    0x3c,
    0x44,
    0x28,
    0x10,
    0x28,
    0x44,
    0x4c,
    0x90,
    0x90,
    0x90,
    0x7c,
    0x44,
    0x64,
    0x54,
    0x4c,
    0x44,
    0x00,
    0x08,
    0x36,
    0x41,
    0x00,
    0x00,
    0x00,
    0x77,
    0x00,
    0x00,
    0x00,
    0x41,
    0x36,
    0x08,
    0x00,
    0x02,
    0x01,
    0x02,
    0x04,
    0x02,
    0x3c,
    0x26,
    0x23,
    0x26,
    0x3c,
    0x1e,
    0xa1,
    0xa1,
    0x61,
    0x12,
    0x3a,
    0x40,
    0x40,
    0x20,
    0x7a,
    0x38,
    0x54,
    0x54,
    0x55,
    0x59,
    0x21,
    0x55,
    0x55,
    0x79,
    0x41,
    0x21,
    0x54,
    0x54,
    0x78,
    0x41,
    0x21,
    0x55,
    0x54,
    0x78,
    0x40,
    0x20,
    0x54,
    0x55,
    0x79,
    0x40,
    0x0c,
    0x1e,
    0x52,
    0x72,
    0x12,
    0x39,
    0x55,
    0x55,
    0x55,
    0x59,
    0x39,
    0x54,
    0x54,
    0x54,
    0x59,
    0x39,
    0x55,
    0x54,
    0x54,
    0x58,
    0x00,
    0x00,
    0x45,
    0x7c,
    0x41,
    0x00,
    0x02,
    0x45,
    0x7d,
    0x42,
    0x00,
    0x01,
    0x45,
    0x7c,
    0x40,
    0xf0,
    0x29,
    0x24,
    0x29,
    0xf0,
    0xf0,
    0x28,
    0x25,
    0x28,
    0xf0,
    0x7c,
    0x54,
    0x55,
    0x45,
    0x00,
    0x20,
    0x54,
    0x54,
    0x7c,
    0x54,
    0x7c,
    0x0a,
    0x09,
    0x7f,
    0x49,
    0x32,
    0x49,
    0x49,
    0x49,
    0x32,
    0x32,
    0x48,
    0x48,
    0x48,
    0x32,
    0x32,
    0x4a,
    0x48,
    0x48,
    0x30,
    0x3a,
    0x41,
    0x41,
    0x21,
    0x7a,
    0x3a,
    0x42,
    0x40,
    0x20,
    0x78,
    0x00,
    0x9d,
    0xa0,
    0xa0,
    0x7d,
    0x39,
    0x44,
    0x44,
    0x44,
    0x39,
    0x3d,
    0x40,
    0x40,
    0x40,
    0x3d,
    0x3c,
    0x24,
    0xff,
    0x24,
    0x24,
    0x48,
    0x7e,
    0x49,
    0x43,
    0x66,
    0x2b,
    0x2f,
    0xfc,
    0x2f,
    0x2b,
    0xff,
    0x09,
    0x29,
    0xf6,
    0x20,
    0xc0,
    0x88,
    0x7e,
    0x09,
    0x03,
    0x20,
    0x54,
    0x54,
    0x79,
    0x41,
    0x00,
    0x00,
    0x44,
    0x7d,
    0x41,
    0x30,
    0x48,
    0x48,
    0x4a,
    0x32,
    0x38,
    0x40,
    0x40,
    0x22,
    0x7a,
    0x00,
    0x7a,
    0x0a,
    0x0a,
    0x72,
    0x7d,
    0x0d,
    0x19,
    0x31,
    0x7d,
    0x26,
    0x29,
    0x29,
    0x2f,
    0x28,
    0x26,
    0x29,
    0x29,
    0x29,
    0x26,
    0x30,
    0x48,
    0x4d,
    0x40,
    0x20,
    0x38,
    0x08,
    0x08,
    0x08,
    0x08,
    0x08,
    0x08,
    0x08,
    0x08,
    0x38,
    0x2f,
    0x10,
    0xc8,
    0xac,
    0xba,
    0x2f,
    0x10,
    0x28,
    0x34,
    0xfa,
    0x00,
    0x00,
    0x7b,
    0x00,
    0x00,
    0x08,
    0x14,
    0x2a,
    0x14,
    0x22,
    0x22,
    0x14,
    0x2a,
    0x14,
    0x08,
    0xaa,
    0x00,
    0x55,
    0x00,
    0xaa,
    0xaa,
    0x55,
    0xaa,
    0x55,
    0xaa,
    0x00,
    0x00,
    0x00,
    0xff,
    0x00,
    0x10,
    0x10,
    0x10,
    0xff,
    0x00,
    0x14,
    0x14,
    0x14,
    0xff,
    0x00,
    0x10,
    0x10,
    0xff,
    0x00,
    0xff,
    0x10,
    0x10,
    0xf0,
    0x10,
    0xf0,
    0x14,
    0x14,
    0x14,
    0xfc,
    0x00,
    0x14,
    0x14,
    0xf7,
    0x00,
    0xff,
    0x00,
    0x00,
    0xff,
    0x00,
    0xff,
    0x14,
    0x14,
    0xf4,
    0x04,
    0xfc,
    0x14,
    0x14,
    0x17,
    0x10,
    0x1f,
    0x10,
    0x10,
    0x1f,
    0x10,
    0x1f,
    0x14,
    0x14,
    0x14,
    0x1f,
    0x00,
    0x10,
    0x10,
    0x10,
    0xf0,
    0x00,
    0x00,
    0x00,
    0x00,
    0x1f,
    0x10,
    0x10,
    0x10,
    0x10,
    0x1f,
    0x10,
    0x10,
    0x10,
    0x10,
    0xf0,
    0x10,
    0x00,
    0x00,
    0x00,
    0xff,
    0x10,
    0x10,
    0x10,
    0x10,
    0x10,
    0x10,
    0x10,
    0x10,
    0x10,
    0xff,
    0x10,
    0x00,
    0x00,
    0x00,
    0xff,
    0x14,
    0x00,
    0x00,
    0xff,
    0x00,
    0xff,
    0x00,
    0x00,
    0x1f,
    0x10,
    0x17,
    0x00,
    0x00,
    0xfc,
    0x04,
    0xf4,
    0x14,
    0x14,
    0x17,
    0x10,
    0x17,
    0x14,
    0x14,
    0xf4,
    0x04,
    0xf4,
    0x00,
    0x00,
    0xff,
    0x00,
    0xf7,
    0x14,
    0x14,
    0x14,
    0x14,
    0x14,
    0x14,
    0x14,
    0xf7,
    0x00,
    0xf7,
    0x14,
    0x14,
    0x14,
    0x17,
    0x14,
    0x10,
    0x10,
    0x1f,
    0x10,
    0x1f,
    0x14,
    0x14,
    0x14,
    0xf4,
    0x14,
    0x10,
    0x10,
    0xf0,
    0x10,
    0xf0,
    0x00,
    0x00,
    0x1f,
    0x10,
    0x1f,
    0x00,
    0x00,
    0x00,
    0x1f,
    0x14,
    0x00,
    0x00,
    0x00,
    0xfc,
    0x14,
    0x00,
    0x00,
    0xf0,
    0x10,
    0xf0,
    0x10,
    0x10,
    0xff,
    0x10,
    0xff,
    0x14,
    0x14,
    0x14,
    0xff,
    0x14,
    0x10,
    0x10,
    0x10,
    0x1f,
    0x00,
    0x00,
    0x00,
    0x00,
    0xf0,
    0x10,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xf0,
    0xf0,
    0xf0,
    0xf0,
    0xf0,
    0xff,
    0xff,
    0xff,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0xff,
    0xff,
    0x0f,
    0x0f,
    0x0f,
    0x0f,
    0x0f,
    0x38,
    0x44,
    0x44,
    0x38,
    0x44,
    0x7c,
    0x2a,
    0x2a,
    0x3e,
    0x14,
    0x7e,
    0x02,
    0x02,
    0x06,
    0x06,
    0x02,
    0x7e,
    0x02,
    0x7e,
    0x02,
    0x63,
    0x55,
    0x49,
    0x41,
    0x63,
    0x38,
    0x44,
    0x44,
    0x3c,
    0x04,
    0x40,
    0x7e,
    0x20,
    0x1e,
    0x20,
    0x06,
    0x02,
    0x7e,
    0x02,
    0x02,
    0x99,
    0xa5,
    0xe7,
    0xa5,
    0x99,
    0x1c,
    0x2a,
    0x49,
    0x2a,
    0x1c,
    0x4c,
    0x72,
    0x01,
    0x72,
    0x4c,
    0x30,
    0x4a,
    0x4d,
    0x4d,
    0x30,
    0x30,
    0x48,
    0x78,
    0x48,
    0x30,
    0xbc,
    0x62,
    0x5a,
    0x46,
    0x3d,
    0x3e,
    0x49,
    0x49,
    0x49,
    0x00,
    0x7e,
    0x01,
    0x01,
    0x01,
    0x7e,
    0x2a,
    0x2a,
    0x2a,
    0x2a,
    0x2a,
    0x44,
    0x44,
    0x5f,
    0x44,
    0x44,
    0x40,
    0x51,
    0x4a,
    0x44,
    0x40,
    0x40,
    0x44,
    0x4a,
    0x51,
    0x40,
    0x00,
    0x00,
    0xff,
    0x01,
    0x03,
    0xe0,
    0x80,
    0xff,
    0x00,
    0x00,
    0x08,
    0x08,
    0x6b,
    0x6b,
    0x08,
    0x36,
    0x12,
    0x36,
    0x24,
    0x36,
    0x06,
    0x0f,
    0x09,
    0x0f,
    0x06,
    0x00,
    0x00,
    0x18,
    0x18,
    0x00,
    0x00,
    0x00,
    0x10,
    0x10,
    0x00,
    0x30,
    0x40,
    0xff,
    0x01,
    0x01,
    0x00,
    0x1f,
    0x01,
    0x01,
    0x1e,
    0x00,
    0x19,
    0x1d,
    0x17,
    0x12,
    0x00,
    0x3c,
    0x3c,
    0x3c,
    0x3c,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
  ];
  