text: /*
      artifact generator: C:\My\wizzi\wizzi-mono\node_modules\wizzi-js\lib\artifacts\js\module\gen\main.js
      primary source IttfDocument: C:\My\wizzi\wizzi-mono\packages\wizzi-helpers\.wizzi\ittf\lib\verify.js.ittf
  */
  'use strict';
  // generated by v6-wizzi-js.artifacts.js.module.main
  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
  
  var util = require('util');
  var path = require('path');
  var chalk = require('chalk');
  var sprintf = require('extsprintf').sprintf;
  var errors = require('./errors');
  var regexpExt = require('./regexpExt');
  var md = module.exports = {};
  md.getAllRegExp = regexpExt.getAllRegExp;
  md.namedRegExp = regexpExt.namedRegExp;
  var isAbsolutePathRegExp = new RegExp('^(?:[a-z]+:)?/', 'i');
  md.isDefined = function(test) {
      return !(typeof(test) === 'undefined');
  };
  md.isUndefined = function(test) {
      return typeof(test) === 'undefined';
  };
  md.isNullOrUndefined = function(test) {
      return test === null || (typeof(test) === 'undefined');
  };
  md.isString = function(test) {
      return test !== null && typeof(test) === 'string';
  };
  md.isEmpty = function(test) {
      return md.isString(test) == false || test.length == 0;
  };
  md.isNotEmpty = function(test) {
      return md.isString(test) && test.length > 0;
  };
  md.isNumber = function(test) {
      if (test === null || typeof(test) === 'undefined') {
          return false;
      }
      return !md.isArray(test) && (test - parseFloat(test) + 1) >= 0;
  };
  md.isBoolean = function(test) {
      return typeof(test) === 'boolean';
  };
  md.isDate = function(test) {
      if (test === null || typeof(test) === 'undefined') {
          return false;
      }
      return Object.prototype.toString.call(test) === '[object Date]';
  };
  md.isPrimitive = function(test) {
      return md.isString(test) || md.isNumber(test) || md.isBoolean(test) || md.isDate(test);
  };
  md.isObject = function(test) {
      if (test === null || typeof(test) === 'undefined') {
          return false;
      }
      return {}.toString.call(test) === '[object Object]';
  };
  md.isArray = function(test) {
      if (test === null || typeof(test) === 'undefined') {
          return false;
      }
      if (Array.isArray) {
          return Array.isArray(test);
      }
      return {}.toString.call(test) === '[object Array]';
  };
  md.isArrayOrObject = function(test) {
      return md.isArray(test) || md.isObject(test);
  };
  md.isFunction = function(test) {
      if (test === null || typeof(test) === 'undefined') {
          return false;
      }
      return {}.toString.call(test) === '[object Function]' || {}.toString.call(test) === '[object AsyncFunction]';
  };
  md.isRegExp = function(test) {
      if (test === null || typeof(test) === 'undefined') {
          return false;
      }
      return {}.toString.call(test) === '[object RegExp]';
  };
  md.isError = function(test) {
      if (test === null || typeof(test) === 'undefined') {
          return false;
      }
      return ({}.toString.call(test) === '[object Error]') || (test instanceof Error);
  };
  md.isAbsolutePath = function(test) {
      if (test === null || typeof(test) === 'undefined') {
          return false;
      }
      return isAbsolutePathRegExp.test(md.unixifyPath(test));
      /**
          if (test.substr(0,3) === 'db:' || test.substr(0,3) === 'ls:') {
              return true;
          }
          return path.resolve(test) == path.normalize(test);
      */
  };
  md.isIttfMacro = function(test) {
      if (md.isEmpty(test)) {
          return false;
      }
      test = test.trim();
      return test.substr(0, 2) === ' && test.substr(-1, 1) === ';
  };
  md.isSingleQuoteLiteral = function(test) {
      if (md.isEmpty(test)) {
          return false;
      }
      test = test.trim();
      return test[0] === "'" && test.substr(-1, 1) === "'";
  };
  md.isDoubleQuoteLiteral = function(test) {
      if (md.isEmpty(test)) {
          return false;
      }
      test = test.trim();
      return test[0] === '"' && test.substr(-1, 1) === '"';
  };
  md.isCssLength = function(test) {
      if (md.isEmpty(test)) {
          return false;
      }
      test = test.trim();
      var num = 0;
      var unit = '';
      for (var i=0; i<test.length; i++) {
          if ('0123456789.'.indexOf(test[i]) > -1) {
              num++;
          }
          else {
              unit += test[i];
          }
      }
      return num > 0 && ['px', 'em', 'rem', 'vh', 'vw'].indexOf(unit) > -1;
  };
  /**
       TODO these Regex(s) are too ingenuous
       research stronger solutions
      
  */
  var ipRegex = /^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$/i,
      emailRegex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
      base64Regex = /[^a-zA-Z0-9\/\+=]/i,
      numericDashRegex = /^[\d\-\s]+$/,
      urlRegex = /^((http|https):\/\/(\w+:{0,1}\w*@)?(\S+)|)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
  md.isEmail = function(value) {
      return md.isNotEmpty(value) && emailRegex.test(value);
  };
  md.isEmails = function(value) {
      if (md.isNotEmpty(value) == false) {
          return false;
      }
      var i, i_items=_toArray(value), i_len=_toArray(value).length, item;
      for (i=0; i<i_len; i++) {
          item = _toArray(value)[i];
          if (!emailRegex.test(item)) {
              return false;
          }
      }
      return true;
  };
  md.isMinLength = function(value, length) {
      return _hasLength(value) && value.length >= length;
  };
  md.isMaxLength = function(value, length) {
      return _hasLength(value) && value.length <= length;
  };
  md.isExactLength = function(value, length) {
      return _hasLength(value) && value.length == length;
  };
  md.isGreaterThan = function(value, test) {
      return md.isNumber(value) && value > test;
  };
  md.isLessThan = function(value, test) {
      return md.isNumber(value) && value < test;
  };
  md.isGreaterEqualThan = function(value, test) {
      return md.isNumber(value) && value >= test;
  };
  md.isLessEqualThan = function(value, test) {
      return md.isNumber(value) && value <= test;
  };
  md.isAlpha = function(value) {
      return md.isNotEmpty(value) && /^[a-z]+$/i.test(value);
  };
  md.isAlphaNumeric = function(value) {
      return md.isNotEmpty(value) && /^[a-z0-9]+$/i.test(value);
  };
  md.isIp = function(value) {
      return md.isNotEmpty(value) && ipRegex.test(value);
  };
  md.isBase64 = function(value) {
      return md.isNotEmpty(value) && base64Regex.test(value);
  };
  md.isUrl = function(value) {
      return md.isNotEmpty(value) && urlRegex.test(value);
  };
  md.isCreditCard = function(value) {
      if (!numericDashRegex.test(value)) {
          return false;
      }
      var nCheck = 0,
          nDigit = 0,
          bEven = false;
      var strippedField = value.replace(/\D/g, "");
      for (var n = (strippedField.length - 1); n >= 0; n--) {
          var cDigit = strippedField.charAt(n);
          nDigit = parseInt(cDigit, 10);
          if (bEven) {
              if (nDigit *= 2 > 9) {
                  nDigit -= 9;
              }
          }
          nCheck += nDigit;
          bEven = !bEven;
      }
      return nCheck % 10 === 0;
  };
  md.isGreaterThanDate = function(value, date) {
      var enteredDate = this._getValidDate(value),
          validDate = this._getValidDate(date);
      if (!validDate || !enteredDate) {
          return false;
      }
      return enteredDate > validDate;
  };
  md.isLessThanDate = function(value, date) {
      var enteredDate = this._getValidDate(value),
          validDate = this._getValidDate(date);
      if (!validDate || !enteredDate) {
          return false;
      }
      return enteredDate < validDate;
  };
  md.isGreaterEqualDate = function(value, date) {
      var enteredDate = this._getValidDate(value),
          validDate = this._getValidDate(date);
      if (!validDate || !enteredDate) {
          return false;
      }
      return enteredDate >= validDate;
  };
  md.isLessEqualDate = function(value, date) {
      var enteredDate = this._getValidDate(value),
          validDate = this._getValidDate(date);
      if (!validDate || !enteredDate) {
          return false;
      }
      return enteredDate <= validDate;
  };
  function _getValidDate(date) {
      if (md.isDate(date)) {
          return date;
      }
      else if (md.isNumber(date)) {
          return new Date(date);
      }
      else if (md.isNotEmpty(date)) {
          if (!date.match('today') && !date.match(dateRegex)) {
              return false;
          }
          var validDate = new Date(),
              validDateArray;
          if (!date.match('today')) {
              validDateArray = date.split('-');
              validDate.setFullYear(validDateArray[0]);
              validDate.setMonth((validDateArray[1] - 1));
              validDate.setDate(validDateArray[2]);
          }
          return validDate;
      }
      else {
          return false;
      }
  }
  function _hasLength(value) {
      return value && md.isNumber(value.length);
  }
  function _toArray(value) {
      if (md.isArray(value)) {
          return value;
      }
      else if (md.isNotEmpty(value)) {
          return value.split(/\s*,\s*/g);
      }
      else {
          return [];
      }
  }
  md.convert = function convert(value, type, unquote) {
      if (value === '@@null') {
          return null;
      }
      if (value === '@@undefined') {
          return undefined;
      }
      if (md.isIttfMacro(value)) {
          return value;
      }
      if (md.isEmpty(type) || type === 'string') {
          if (md.isString(value)) {
              if (unquote) {
                  return md.unquote(value);
              }
              else {
                  return value;
              }
          }
          else {
              return '';
          }
      }
      else if (type == 'integer') {
          if (md.canConvertTo(type, value)) {
              return parseInt(value, 10);
          }
          else {
              return error('TypeError', 'convert', 'Cannot convert ' + value + ' to integer');
          }
      }
      else if (type == 'float') {
          if (md.canConvertTo(type, value)) {
              return parseFloat(value);
          }
          else {
              return error('TypeError', 'convert', 'Cannot convert ' + value + ' to float');
          }
      }
      else if (type == 'boolean') {
          if (md.canConvertTo(type, value)) {
              return value === 'true' ? true : false;
          }
          else {
              return error('TypeError', 'convert', 'Cannot convert ' + value + ' to boolean');
          }
      }
      else if (type == 'date') {
          if (md.canConvertTo(type, value)) {
              var parts = value.split('-');
              return new Date(parts[0], parts[1] - 1, parts[2]);
          }
          else {
              return error('TypeError', 'convert', 'Cannot convert ' + value + ' to date');
          }
      }
      return error('TypeError', 'convert', 'Invalid type: "' + type + '", expected (string, integer, float, boolean, date)');
  };
  // means can convert a not empty string value to a given type
  md.canConvertTo = function(type, value) {
      if (type === 'boolean') {
          return value === 'true' || value === 'false';
      }
      else if (type === 'integer') {
          return /^\-?[0-9]+$/.test(value);
      }
      else if (type === 'float') {
          return /^\-?[0-9]*\.?[0-9]+$/.test(value);
      }
      else if (type === 'date') {
          return /\d{4}-\d{1,2}-\d{1,2}/.test(value);
      }
      else if (type === 'string') {
          return true;
      }
  };
  md.escapeQuotes = function(text) {
      if (!text) {
          return ;
      }
      text = md.replaceAll(text, "'", "\\'");
      return md.replaceAll(text, '"', '\\"');
  };
  md.splitLines = function(text, options) {
      if (!text) {
          return [];
      }
      options = options || {};
      if (options.numbered) {
          var lines = text.split(/\r?\n/);
          var ret = [];
          var i, i_items=lines, i_len=lines.length, line;
          for (i=0; i<i_len; i++) {
              line = lines[i];
              ret.push({
                  num: i, 
                  numFmt: i < 10 ? '000' + i : i <100 ? '00' + i : '0' + i, 
                  text: line
              });
          }
          return ret;
      }
      else {
          return text.split(/\r?\n/);
      }
  };
  md.stripIttfExtension = function(path_string) {
      if (!path_string) {
          return path_string;
      }
      if (md.endsWith(path_string, '.ittf')) {
          return md.stripExtension(path_string);
      }
      else {
          return path_string;
      }
  };
  md.stripExtension = function(path_string) {
      if (!path_string) {
          return path_string;
      }
      var pos = path_string.lastIndexOf('.');
      return path_string.substr(0, pos);
  };
  md.replaceExtension = function(path_string, newExtension) {
      if (!path_string) {
          return path_string;
      }
      return md.stripExtension(path_string) + '.' + newExtension;
  };
  var STATE_WAIT_NAME = 0;
  var STATE_NAME = 1;
  var STATE_WAIT_VALUE = 2;
  var STATE_VALUE = 3;
  var STATE_ENDED = 4;
  var STATE_NAME_BRACKET = 5;
  md.parseNameValue = function(text, node, options) {
      options = options || {};
      var isObjectProperty = options.objectProperty;
      var name_buf = [];
      var value_buf = [];
      if (md.isNotEmpty(text)) {
          var ch,
              l = text.length,
              state = 0,
              q = null,
              bracketLevel = 0;
          for (var i = 0; i < l; i++) {
              ch = text[i];
              if (state == STATE_NAME_BRACKET) {
                  name_buf.push(ch);
                  if (ch == ']') {
                      bracketLevel--;
                      if (bracketLevel == 0) {
                          state = STATE_WAIT_VALUE;
                      }
                  }
                  else if (ch == '[') {
                      bracketLevel++;
                  }
              }
              else if (isObjectProperty && state == STATE_WAIT_NAME && ch == '[') {
                  name_buf.push(ch);
                  state = STATE_NAME_BRACKET;
                  bracketLevel++;
              }
              else if (q != null) {
                  // state MUST BE STATE_NAME or STATE_VALUE
                  if (state === STATE_NAME) {
                      name_buf.push(ch);
                  }
                  else if (state === STATE_VALUE) {
                      value_buf.push(ch);
                  }
                  else {
                      // this is a bug
                      throw new Error('BUG. parseNameValue invalid state ' + state);
                  }
                  if (ch == '\\') {
                      i++;
                      ch = text[i];
                      if (state === STATE_NAME) {
                          name_buf.push(ch);
                      }
                      else if (state === STATE_VALUE) {
                          value_buf.push(ch);
                      }
                  }
                  else if (ch == q) {
                      q = null;
                      if (state === STATE_NAME) {
                          state = STATE_WAIT_VALUE;
                      }
                  }
              }
              else if (ch == '"' || ch == '\'') {
                  // state MUST BE STATE_WAIT_NAME or STATE_WAIT_VALUE
                  if (state === STATE_NAME) {
                      throw new errors.NodeError("parseNameValue error. Invalid use of quote inside a name part. Source: " + text, node);
                  }
                  else if (state === STATE_VALUE) {
                      value_buf.push(ch);
                  }
                  else if (state === STATE_ENDED) {
                      throw new errors.NodeError("parseNameValue error. Invalid quote found after value. Source: " + text, node);
                  }
                  else if (state === STATE_WAIT_NAME) {
                      state = STATE_NAME;
                      name_buf.push(ch);
                      q = ch;
                  }
                  else if (state === STATE_WAIT_VALUE) {
                      state = STATE_VALUE;
                      value_buf.push(ch);
                      q = ch;
                  }
              }
              else if (ch == ' ' || ch == '\t') {
                  if (state === STATE_NAME) {
                      state = STATE_WAIT_VALUE;
                  }
                  else if (state === STATE_VALUE) {
                      value_buf.push(ch);
                  }
                  else {
                      // ok. no action.
                  }
              }
              else if (ch == '\r' || ch == '\n') {
                  throw new errors.NodeError("parseNameValue error. Invalid char. Line cannot contain line breaks. Source: " + text, node);
              }
              else {
                  if (state === STATE_WAIT_NAME) {
                      state = STATE_NAME;
                      name_buf.push(ch);
                  }
                  else if (state === STATE_WAIT_VALUE) {
                      state = STATE_VALUE;
                      value_buf.push(ch);
                  }
                  else if (state === STATE_NAME) {
                      name_buf.push(ch);
                  }
                  else if (state === STATE_VALUE) {
                      value_buf.push(ch);
                  }
                  else if (state === STATE_ENDED) {
                      throw new errors.NodeError("parseNameValue error. Invalid char after value. Source: " + text, node);
                  }
              }
          }
      }
      if (q !== null && state === STATE_NAME) {
          // This almost surely is an error, but we cannot judge.
      }
      return {
              name: function() {
                  return name_buf.join('');
              }, 
              value: function() {
                  return value_buf.join('');
              }, 
              hasValue: function() {
                  return value_buf.length > 0;
              }
          };
  };
  md.isArtifact = function(test) {
      if (!md.isDefined(test) || test === null) {
          return false;
      }
      if (!md.isFunction(test.generate)) {
          return false;
      }
      if (!md.isFunction(test.toFile)) {
          return false;
      }
      if (!md.isFunction(test.generateToFile)) {
          return false;
      }
      return true;
  };
  md.getInterfaceMessage = function() {
      return "generate(...), toFile(...), generateToFile(...)";
  };
  md.startsWith = function(str, prefix) {
      if (md.isEmpty(str) || md.isEmpty(prefix)) {
          return false;
      }
      else {
          return str.indexOf(prefix) === 0;
      }
  };
  md.endsWith = function(str, suffix) {
      if (md.isEmpty(str) || md.isEmpty(suffix)) {
          return false;
      }
      else {
          return str.indexOf(suffix, str.length - suffix.length) !== -1;
      }
  };
  md.unquote = function(str) {
      if (md.isString(str) === false) {
          return str;
      }
      if (str.length < 2) {
          return str;
      }
      if ((str.substr(0, 1) === "'" && str.substr(-1, 1) === "'" && str.substr(1, str.length -2).indexOf("'") == -1) || (str.substr(0, 1) === "\"" && str.substr(-1, 1) === "\""  && str.substr(1, str.length -2).indexOf("\"") == -1)) {
          return str.substr(1, str.length -2);
      }
      else {
          return str;
      }
  };
  md.capitalize = function(str) {
      if (md.isEmpty(str)) {
          return str;
      }
      return str.substr(0, 1).toUpperCase() + str.substr(1);
  };
  md.dashToCamelCase = function(str) {
      if (md.isEmpty(str)) {
          return str;
      }
      return str.replace(/-([a-z])/g, function(g) {
              return g[1].toUpperCase();
          });
  };
  md.replaceAll = function(text, find, replace) {
      if (md.isEmpty(text)) {
          return text;
      }
      // log 'replaceAll', text, '-', find, '-', md.escapeRegExp(find), '-', replace
      return text.replace(new RegExp(md.escapeRegExp(find), 'g'), replace);
  };
  md.escapeRegExp = function(text) {
      if (md.isEmpty(text)) {
          return text;
      }
      return text.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
  };
  md.htmlEscape = function escape(value) {
      if (md.isEmpty(value)) {
          return value;
      }
      value = md.replaceAll(value, '<', '&lt;');
      value = md.replaceAll(value, '>', '&gt;');
      return value;
  };
  md.resolveToString = function(paramValue) {
      if (md.isNotEmpty(paramValue)) {
          return paramValue;
      }
      if (md.isFunction(paramValue)) {
          var value = paramValue();
          if (md.isNotEmpty(value)) {
              return value;
          }
      }
      return null;
  };
  md.makeInline = function(text) {
      // 192: └ , 191: ┐ , 190: ¥
      return md.replaceAll(md.replaceAll(md.replaceAll(text, '\n', '¥'), '\r', '┐'), '$', '└');
  };
  var win32 = process.platform === 'win32';
  md.unixifyPath = function(path_string) {
      if (win32) {
          return path_string.replace(/\\/g, '/');
      }
      else {
          return path_string;
      }
  };
  var wzError = (function (Error) {
      _inherits(wzError, Error);
      function wzError(name, inner, shortmessage, message, info, stack) {
          _get(Object.getPrototypeOf(wzError.prototype), 'constructor', this).call(this);
          _classCallCheck(this, wzError);
          this.name = name;
          this.inner = inner;
          this.shortmessage = shortmessage;
          this.message = message;
          this.info = info;
          this.stack = stack;
          this.__is_error = true;
          if (md.isNotEmpty(stack)) {
              this.stack = [];
              var i, i_items=stack.split('\n'), i_len=stack.split('\n').length, line;
              for (i=0; i<i_len; i++) {
                  line = stack.split('\n')[i];
                  this.stack.push('    ' + line);
              }
          }
      }
      wzError.prototype.toString = function() {
          var ret = [
              (this.hasOwnProperty('name') && this.name || this.constructor.name || this.constructor.prototype.name) + ': ' + ( this.message || 'message unavailable')
          ];
          if (this.info) {
              for (var k in this.info) {
                  if (md.isPrimitive(this.info[k])) {
                      ret.push( '-> ' + k + ': ' + this.info[k] );
                  }
              }
          }
          if (this.errorLines) {
              ret.push('-> error lines');
              var i, i_items=this.errorLines, i_len=this.errorLines.length, l;
              for (i=0; i<i_len; i++) {
                  l = this.errorLines[i];
                  ret.push(l);
              }
          }
          if (this.inner) {
              // log 'wizzi-utils.verify.wzError.toString.this.inner', this.inner
              var inner = this.inner;
              while (inner) {
                  var stack = inner.stack;
                  if (md.isNotEmpty(stack)) {
                      ret.push( '-> inner.stack :');
                      var i, i_items=stack.split('\n'), i_len=stack.split('\n').length, line;
                      for (i=0; i<i_len; i++) {
                          line = stack.split('\n')[i];
                          ret.push('    ' + line);
                      }
                      inner = null;
                  }
                  else {
                      inner = inner.inner;
                  }
              }
          }
          return ret.join('\n');
      }
      wzError.prototype.toInfo = function() {
          var ret = [
              '\n', 
              '== error =================='
          ];
          for (var k in this.info) {
              if (md.isPrimitive(this.info[k])) {
                  ret.push( '-> ' + k + ': ' + this.info[k] );
              }
          }
          ret.push('---------------------------');
          if (this.errorLines) {
              ret.push('-- error lines');
              var i, i_items=this.errorLines, i_len=this.errorLines.length, l;
              for (i=0; i<i_len; i++) {
                  l = this.errorLines[i];
                  ret.push(l);
              }
          }
          return ret.join('\n');
      }
      return wzError;
  })(Error);
  
  wzError.prototype.name = 'wzError';
  md.assert = {
      notEmpty: function(test, message) {
          if (md.isNotEmpty(test) === false) {
              md.fatal(message);
          }
      }
  };
  md.code = {
      FATAL_ERROR: 1, 
      WARNING: 10
  };
  md.error = function() {
      var args = Array.prototype.slice.call(arguments, 0),
          name = null,
          inner = null,
          shortmessage = null,
          message = null,
          info = {},
          sprintf_args = [],
          stack;
      var i, i_items=args, i_len=args.length, arg;
      for (i=0; i<i_len; i++) {
          arg = args[i];
          if (md.isError(arg)) {
              console.log('wizzi-utils.verify.errors.error. seen inner', arg.message, arg.stack);
              inner = arg;
          }
          else if (typeof (arg) === 'object' && sprintf_args.length == 0) {
              for (var k in arg) {
                  if (k === 'name') {
                      md.assert.notEmpty(arg[k], 'error\'s "name" must be a string. Received: ' + util.inspect(arg[k], { depth: null }));
                      name = arg[k];
                  }
                  else {
                      info[k] = arg[k];
                  }
              }
          }
          else {
              if (sprintf_args.length == 0 && arg === null || typeof(arg) === 'undefined') {
                  // skip empty inner error or empty object
              }
              else {
                  sprintf_args.push(arg);
              }
          }
      }
      if (sprintf_args.length > 0) {
          md.assert.notEmpty(sprintf_args[0], 'First sprintf argument to wzError ' + 'constructor must be a string. Received: ' + util.inspect(sprintf_args[0], { depth: null }));
      }
      shortmessage = sprintf_args.length === 0 ? '' : sprintf.apply(null, sprintf_args);
      message = shortmessage;
      if (inner && md.isError(inner)) {
          message += ': ' + inner.message;
          stack = inner.stack;
      }
      return new wzError(name, inner, shortmessage, message, info, stack);
  };
  md.fatal = function(err, errcode) {
      console.log('wizzi-utils.errors.fatal', util.inspect(err, { depth: null }));
      throw new Error(err);
      logerror("Fatal error: " + String(err.message || err));
      dumpStack(err);
      var code = typeof(errcode) === 'number' ? errcode : md.code.FATAL_ERROR;
      ;
      process.exit(code);
  };
  function loginfo(msg) {
      console.log(msg);
  }
  function logwarn(msg) {
      console.log(chalk.yellow(msg));
  }
  function logerror(msg) {
      console.log(chalk.red(msg));
  }
  function dumpStack(e) {
      if (e.origError && e.origError.stack) {
          loginfo(e.origError.stack);
      }
      else if (e.stack) {
          loginfo(e.stack);
      }
      else {
          loginfo(new Error().stack());
      }
  }
  function error(code, method, message, innerError) {
      var parameter = null;
      if (md.isObject(message)) {
          parameter = message.parameter;
          message = message.message;
      }
      return md.error(innerError, {
              name: ( md.isNumber(code) ? 'Err-' + code : code ), 
              method: 'wizzi-utils.verify.' + method, 
              parameter: parameter, 
              sourcePath: __filename
          }, message || 'Error message unavailable');
  }
  