text: {{# def.definitions }}
  {{# def.errors }}
  {{# def.setupKeyword }}
  {{# def.setupNextLevel }}
  
  
  {{## def.validateAdditional:
    {{ /* additionalProperties is schema */
      $it.schema = $aProperties;
      $it.schemaPath = it.schemaPath + '.additionalProperties';
      $it.errSchemaPath = it.errSchemaPath + '/additionalProperties';
      $it.errorPath = it.opts._errorDataPathProperty
                      ? it.errorPath
                      : it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers);
      var $passData = $data + '[' + $key + ']';
      $it.dataPathArr[$dataNxt] = $key;
    }}
  
    {{# def.generateSubschemaCode }}
    {{# def.optimizeValidate }}
  #}}
  
  
  {{
    var $key = 'key' + $lvl
      , $idx = 'idx' + $lvl
      , $dataNxt = $it.dataLevel = it.dataLevel + 1
      , $nextData = 'data' + $dataNxt
      , $dataProperties = 'dataProperties' + $lvl;
  
    var $schemaKeys = Object.keys($schema || {})
      , $pProperties = it.schema.patternProperties || {}
      , $pPropertyKeys = Object.keys($pProperties)
      , $aProperties = it.schema.additionalProperties
      , $someProperties = $schemaKeys.length || $pPropertyKeys.length
      , $noAdditional = $aProperties === false
      , $additionalIsSchema = typeof $aProperties == 'object'
                                && Object.keys($aProperties).length
      , $removeAdditional = it.opts.removeAdditional
      , $checkAdditional = $noAdditional || $additionalIsSchema || $removeAdditional
      , $ownProperties = it.opts.ownProperties
      , $currentBaseId = it.baseId;
  
    var $required = it.schema.required;
    if ($required && !(it.opts.$data && $required.$data) && $required.length < it.opts.loopRequired)
      var $requiredHash = it.util.toHash($required);
  }}
  
  
  var {{=$errs}} = errors;
  var {{=$nextValid}} = true;
  {{? $ownProperties }}
    var {{=$dataProperties}} = undefined;
  {{?}}
  
  {{? $checkAdditional }}
    {{# def.iterateProperties }}
      {{? $someProperties }}
        var isAdditional{{=$lvl}} = !(false
          {{? $schemaKeys.length }}
            {{? $schemaKeys.length > 8 }}
              || validate.schema{{=$schemaPath}}.hasOwnProperty({{=$key}})
            {{??}}
              {{~ $schemaKeys:$propertyKey }}
                || {{=$key}} == {{= it.util.toQuotedString($propertyKey) }}
              {{~}}
            {{?}}
          {{?}}
          {{? $pPropertyKeys.length }}
            {{~ $pPropertyKeys:$pProperty:$i }}
              || {{= it.usePattern($pProperty) }}.test({{=$key}})
            {{~}}
          {{?}}
        );
  
        if (isAdditional{{=$lvl}}) {
      {{?}}
      {{? $removeAdditional == 'all' }}
        delete {{=$data}}[{{=$key}}];
      {{??}}
        {{
          var $currentErrorPath = it.errorPath;
          var $additionalProperty = '\' + ' + $key + ' + \'';
          if (it.opts._errorDataPathProperty) {
            it.errorPath = it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers);
          }
        }}
        {{? $noAdditional }}
          {{? $removeAdditional }}
            delete {{=$data}}[{{=$key}}];
          {{??}}
            {{=$nextValid}} = false;
            {{
              var $currErrSchemaPath = $errSchemaPath;
              $errSchemaPath = it.errSchemaPath + '/additionalProperties';
            }}
            {{# def.error:'additionalProperties' }}
            {{ $errSchemaPath = $currErrSchemaPath; }}
            {{? $breakOnError }} break; {{?}}
          {{?}}
        {{?? $additionalIsSchema }}
          {{? $removeAdditional == 'failing' }}
            var {{=$errs}} = errors;
            {{# def.setCompositeRule }}
  
            {{# def.validateAdditional }}
  
            if (!{{=$nextValid}}) {
              errors = {{=$errs}};
              if (validate.errors !== null) {
                if (errors) validate.errors.length = errors;
                else validate.errors = null;
              }
              delete {{=$data}}[{{=$key}}];
            }
  
            {{# def.resetCompositeRule }}
          {{??}}
            {{# def.validateAdditional }}
            {{? $breakOnError }} if (!{{=$nextValid}}) break; {{?}}
          {{?}}
        {{?}}
        {{ it.errorPath = $currentErrorPath; }}
      {{?}}
      {{? $someProperties }}
        }
      {{?}}
    }
  
    {{# def.ifResultValid }}
  {{?}}
  
  {{ var $useDefaults = it.opts.useDefaults && !it.compositeRule; }}
  
  {{? $schemaKeys.length }}
    {{~ $schemaKeys:$propertyKey }}
      {{ var $sch = $schema[$propertyKey]; }}
  
      {{? {{# def.nonEmptySchema:$sch}} }}
        {{
          var $prop = it.util.getProperty($propertyKey)
            , $passData = $data + $prop
            , $hasDefault = $useDefaults && $sch.default !== undefined;
          $it.schema = $sch;
          $it.schemaPath = $schemaPath + $prop;
          $it.errSchemaPath = $errSchemaPath + '/' + it.util.escapeFragment($propertyKey);
          $it.errorPath = it.util.getPath(it.errorPath, $propertyKey, it.opts.jsonPointers);
          $it.dataPathArr[$dataNxt] = it.util.toQuotedString($propertyKey);
        }}
  
        {{# def.generateSubschemaCode }}
  
        {{? {{# def.willOptimize }} }}
          {{
            $code = {{# def._optimizeValidate }};
            var $useData = $passData;
          }}
        {{??}}
          {{ var $useData = $nextData; }}
          var {{=$nextData}} = {{=$passData}};
        {{?}}
  
        {{? $hasDefault }}
          {{= $code }}
        {{??}}
          {{? $requiredHash && $requiredHash[$propertyKey] }}
            if ({{# def.noPropertyInData }}) {
              {{=$nextValid}} = false;
              {{
                var $currentErrorPath = it.errorPath
                  , $currErrSchemaPath = $errSchemaPath
                  , $missingProperty = it.util.escapeQuotes($propertyKey);
                if (it.opts._errorDataPathProperty) {
                  it.errorPath = it.util.getPath($currentErrorPath, $propertyKey, it.opts.jsonPointers);
                }
                $errSchemaPath = it.errSchemaPath + '/required';
              }}
              {{# def.error:'required' }}
              {{ $errSchemaPath = $currErrSchemaPath; }}
              {{ it.errorPath = $currentErrorPath; }}
            } else {
          {{??}}
            {{? $breakOnError }}
              if ({{# def.noPropertyInData }}) {
                {{=$nextValid}} = true;
              } else {
            {{??}}
              if ({{=$useData}} !== undefined
                {{? $ownProperties }}
                  && {{# def.isOwnProperty }}
                {{?}}
              ) {
            {{?}}
          {{?}}
  
            {{= $code }}
          }
        {{?}}  {{ /* $hasDefault */ }}
      {{?}} {{ /* def.nonEmptySchema */ }}
  
      {{# def.ifResultValid }}
    {{~}}
  {{?}}
  
  {{? $pPropertyKeys.length }}
    {{~ $pPropertyKeys:$pProperty }}
      {{ var $sch = $pProperties[$pProperty]; }}
  
      {{? {{# def.nonEmptySchema:$sch}} }}
        {{
          $it.schema = $sch;
          $it.schemaPath = it.schemaPath + '.patternProperties' + it.util.getProperty($pProperty);
          $it.errSchemaPath = it.errSchemaPath + '/patternProperties/'
                                               + it.util.escapeFragment($pProperty);
        }}
  
        {{# def.iterateProperties }}
          if ({{= it.usePattern($pProperty) }}.test({{=$key}})) {
            {{
              $it.errorPath = it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers);
              var $passData = $data + '[' + $key + ']';
              $it.dataPathArr[$dataNxt] = $key;
            }}
  
            {{# def.generateSubschemaCode }}
            {{# def.optimizeValidate }}
  
            {{? $breakOnError }} if (!{{=$nextValid}}) break; {{?}}
          }
          {{? $breakOnError }} else {{=$nextValid}} = true; {{?}}
        }
  
        {{# def.ifResultValid }}
      {{?}} {{ /* def.nonEmptySchema */ }}
    {{~}}
  {{?}}
  
  
  {{? $breakOnError }}
    {{= $closingBraces }}
    if ({{=$errs}} == errors) {
  {{?}}
  
  {{# def.cleanUp }}
  