text:
require 'strscan'
require 'haml/shared'

module Haml
  # Handles the internal pre-compilation from Haml into Ruby code,
  # which then runs the final creation of the HTML string.
  module Precompiler
    include Haml::Util

    # Designates an XHTML/XML element.
    ELEMENT         = ?%

    # Designates a `<div>` element with the given class.
    DIV_CLASS       = ?.

    # Designates a `<div>` element with the given id.
    DIV_ID          = ?#

    # Designates an XHTML/XML comment.
    COMMENT         = ?/

    # Designates an XHTML doctype or script that is never HTML-escaped.
    DOCTYPE         = ?!

    # Designates script, the result of which is output.
    SCRIPT          = ?=

    # Designates script that is always HTML-escaped.
    SANITIZE        = ?&

    # Designates script, the result of which is flattened and output.
    FLAT_SCRIPT     = ?~

    # Designates script which is run but not output.
    SILENT_SCRIPT   = ?-

    # When following SILENT_SCRIPT, designates a comment that is not output.
    SILENT_COMMENT  = ?#

    # Designates a non-parsed line.
    ESCAPE          = ?\\

    # Designates a block of filtered text.
    FILTER          = ?:

    # Designates a non-parsed line. Not actually a character.
    PLAIN_TEXT      = -1

    # Keeps track of the ASCII values of the characters that begin a
    # specially-interpreted line.
    SPECIAL_CHARACTERS   = [
      ELEMENT,
      DIV_CLASS,
      DIV_ID,
      COMMENT,
      DOCTYPE,
      SCRIPT,
      SANITIZE,
      FLAT_SCRIPT,
      SILENT_SCRIPT,
      ESCAPE,
      FILTER
    ]

    # The value of the character that designates that a line is part
    # of a multiline string.
    MULTILINE_CHAR_VALUE = ?|

    # Regex to match keywords that appear in the middle of a Ruby block
    # with lowered indentation.
    # If a block has been started using indentation,
    # lowering the indentation with one of these won't end the block.
    # For example:
    #
    #   - if foo
    #     %p yes!
    #   - else
    #     %p no!
    #
    # The block is ended after `%p no!`, because `else`
    # is a member of this array.
    MID_BLOCK_KEYWORD_REGEX = /^-\s*(#{%w[else elsif rescue ensure when end].join('|')})\b/

    # The Regex that matches a Doctype command.
    DOCTYPE_REGEX = /(\d(?:\.\d)?)?[\s]*([a-z]*)/i

    # The Regex that matches a literal string or symbol value
    LITERAL_VALUE_REGEX = /:(\w*)|(["'])((?![\\#]|\2).|\\.)*\2/

    private

    # Returns the precompiled string with the preamble and postamble
    def precompiled_with_ambles(local_names)
      preamble = <<END.gsub("\n", ";")
begin
extend Haml::Helpers
_hamlout = @haml_buffer = Haml::Buffer.new(@haml_buffer, #{options_for_buffer.inspect})
_erbout = _hamlout.buffer
__in_erb_template = true
END
      postamble = <<END.gsub("\n", ";")
#{precompiled_method_return_value}
ensure
@haml_buffer = @haml_buffer.upper
end
END
      preamble + locals_code(local_names) + precompiled + postamble
    end

    # Returns the string used as the return value of the precompiled method.
    # This method exists so it can be monkeypatched to return modified values.
    def precompiled_method_return_value
      "_erbout"
    end

    def locals_code(names)
      names = names.keys if Hash == names

      names.map do |name|
        # Can't use || because someone might explicitly pass in false with a symbol
        sym_local = "_haml_locals[#{inspect(name.to_sym)}]"
        str_local = "_haml_locals[#{inspect(name.to_s)}]"
        "#{name} = #{sym_local}.nil? ? #{str_local} : #{sym_local}"
      end.join(';') + ';'
    end

    # @private
    class Line < Struct.new(:text, :unstripped, :full, :index, :precompiler, :eod)
      alias_method :eod?, :eod

      # @private
      def tabs
        line = self
        @tabs ||= precompiler.instance_eval do
          break 0 if line.text.empty? || !(whitespace = line.full[/^\s+/])

          if @indentation.nil?
            @indentation = whitespace

            if @indentation.include?(?\s) && @indentation.include?(?\t)
              raise SyntaxError.new("Indentation can't use both tabs and spaces.", line.index)
            end

            @flat_spaces = @indentation * @template_tabs if flat?
            break 1
          end

          tabs = whitespace.length / @indentation.length
          break tabs if whitespace == @indentation * tabs
          break @template_tabs if flat? && whitespace =~ /^#{@indentation * @template_tabs}/

          raise SyntaxError.new(<<END.strip.gsub("\n", ' '), line.index)
Inconsistent indentation: #{Haml::Shared.human_indentation whitespace, true} used for indentation,
but the rest of the document was indented using #{Haml::Shared.human_indentation @indentation}.
END
        end
      end
    end

    def precompile
      @haml_comment = @dont_indent_next_line = @dont_tab_up_next_text = false
      @indentation = nil
      @line = next_line
      resolve_newlines
      newline

      raise SyntaxError.new("Indenting at the beginning of the document is illegal.", @line.index) if @line.tabs != 0

      while next_line
        process_indent(@line) unless @line.text.empty?

        if flat?
          push_flat(@line)
          @line = @next_line
          next
        end

        process_line(@line.text, @line.index) unless @line.text.empty? || @haml_comment

        if !flat? && @next_line.tabs - @line.tabs > 1
          raise SyntaxError.new("The line was indented #{@next_line.tabs - @line.tabs} levels deeper than the previous line.", @next_line.index)
        end

        resolve_newlines unless @next_line.eod?
        @line = @next_line
        newline unless @next_line.eod?
      end

      # Close all the open tags
      close until @to_close_stack.empty?
      flush_merged_text
    end

    # Processes and deals with lowering indentation.
    def process_indent(line)
      return unless line.tabs <= @template_tabs && @template_tabs > 0

      to_close = @template_tabs - line.tabs
      to_close.times {|i| close unless to_close - 1 - i == 0 && mid_block_keyword?(line.text)}
    end

    # Processes a single line of Haml.
    #
    # This method doesn't return anything; it simply processes the line and
    # adds the appropriate code to `@precompiled`.
    def process_line(text, index)
      @index = index + 1

      case text[0]
      when DIV_CLASS; render_div(text)
      when DIV_ID
        return push_plain(text) if text[1] == ?{
        render_div(text)
      when ELEMENT; render_tag(text)
      when COMMENT; render_comment(text[1..-1].strip)
      when SANITIZE
        return push_plain(text[3..-1].strip, :escape_html => true) if text[1..2] == "=="
        return push_script(text[2..-1].strip, :escape_html => true) if text[1] == SCRIPT
        return push_flat_script(text[2..-1].strip, :escape_html => true) if text[1] == FLAT_SCRIPT
        return push_plain(text[1..-1].strip, :escape_html => true) if text[1] == ?\s
        push_plain text
      when SCRIPT
        return push_plain(text[2..-1].strip) if text[1] == SCRIPT
        push_script(text[1..-1])
      when FLAT_SCRIPT; push_flat_script(text[1..-1])
      when SILENT_SCRIPT
        return start_haml_comment if text[1] == SILENT_COMMENT

        raise SyntaxError.new(<<END.rstrip, index) if text[1..-1].strip == "end"
You don't need to use "- end" in Haml. Un-indent to close a block:
- if foo?
  %strong Foo!
- else
  Not foo.
%p This line is un-indented, so it isn't part of the "if" block
END

        text = handle_ruby_multiline(text)
        push_silent(text[1..-1], true)
        newline_now

        # Handle stuff like - end.join("|")
        @to_close_stack.last << false if text =~ /^-\s*end\b/ && !block_opened?

        keyword = mid_block_keyword?(text)
        block = block_opened? && !keyword

        # It's important to preserve tabulation modification for keywords
        # that involve choosing between posible blocks of code.
        if %w[else elsif when].include?(keyword)
          # Whether a script block has already been opened immediately above this line
          was_opened = @to_close_stack.last && @to_close_stack.last.first == :script
          if was_opened
            @dont_indent_next_line, @dont_tab_up_next_text = @to_close_stack.last[1..2]
          end

          # when is unusual in that either it will be indented twice,
          # or the case won't have created its own indentation.
          # Also, if no block has been opened yet, we need to make sure we add an end
          # once we de-indent.
          if !was_opened || keyword == "when"
            push_and_tabulate([
                :script, @dont_indent_next_line, @dont_tab_up_next_text,
                !was_opened])
          end
        elsif block || text =~ /^-\s*(case|if)\b/
          push_and_tabulate([:script, @dont_indent_next_line, @dont_tab_up_next_text])
        end
      when FILTER; start_filtered(text[1..-1].downcase)
      when DOCTYPE
        return render_doctype(text) if text[0...3] == '!!!'
        return push_plain(text[3..-1].strip, :escape_html => false) if text[1..2] == "=="
        return push_script(text[2..-1].strip, :escape_html => false) if text[1] == SCRIPT
        return push_flat_script(text[2..-1].strip, :escape_html => false) if text[1] == FLAT_SCRIPT
        return push_plain(text[1..-1].strip, :escape_html => false) if text[1] == ?\s
        push_plain text
      when ESCAPE; push_plain text[1..-1]
      else push_plain text
      end
    end

    # If the text is a silent script text with one of Ruby's mid-block keywords,
    # returns the name of that keyword.
    # Otherwise, returns nil.
    def mid_block_keyword?(text)
      text[MID_BLOCK_KEYWORD_REGEX, 1]
    end

    # Evaluates `text` in the context of the scope object, but
    # does not output the result.
    def push_silent(text, can_suppress = false)
      flush_merged_text
      return if can_suppress && options[:suppress_eval]
      @precompiled << "#{text};"
    end

    # Adds `text` to `@buffer` with appropriate tabulation
    # without parsing it.
    def push_merged_text(text, tab_change = 0, indent = true)
      text = !indent || @dont_indent_next_line || @options[:ugly] ? text : "#{'  ' * @output_tabs}#{text}"
      @to_merge << [:text, text, tab_change]
      @dont_indent_next_line = false
    end

    # Concatenate `text` to `@buffer` without tabulation.
    def concat_merged_text(text)
      @to_merge << [:text, text, 0]
    end

    def push_text(text, tab_change = 0)
      push_merged_text("#{text}\n", tab_change)
    end

    def flush_merged_text
      return if @to_merge.empty?

      str = ""
      mtabs = 0
      newlines = 0
      @to_merge.each do |type, val, tabs|
        case type
        when :text
          str << inspect(val)[1...-1]
          mtabs += tabs
        when :script
          if mtabs != 0 && !@options[:ugly]
            val = "_hamlout.adjust_tabs(#{mtabs}); " + val
          end
          str << "\#{#{"\n" * newlines}#{val}}"
          mtabs = 0
          newlines = 0
        when :newlines
          newlines += val
        else
          raise SyntaxError.new("[HAML BUG] Undefined entry in Haml::Precompiler@to_merge.")
        end
      end

      unless str.empty?
        @precompiled <<
          if @options[:ugly]
            "_hamlout.buffer << \"#{str}\";"
          else
            "_hamlout.push_text(\"#{str}\", #{mtabs}, #{@dont_tab_up_next_text.inspect});"
          end
      end
      @precompiled << "\n" * newlines
      @to_merge = []
      @dont_tab_up_next_text = false
    end

    # Renders a block of text as plain text.
    # Also checks for an illegally opened block.
    def push_plain(text, options = {})
      if block_opened?
        raise SyntaxError.new("Illegal nesting: nesting within plain text is illegal.", @next_line.index)
      end

      if contains_interpolation?(text)
        options[:escape_html] = self.options[:escape_html] if options[:escape_html].nil?
        push_script(
          unescape_interpolation(text, :escape_html => options[:escape_html]),
          :escape_html => false)
      else
        push_text text
      end
    end

    # Adds +text+ to `@buffer` while flattening text.
    def push_flat(line)
      text = line.full.dup
      text = "" unless text.gsub!(/^#{@flat_spaces}/, '')
      @filter_buffer << "#{text}\n"
    end

    # Causes `text` to be evaluated in the context of
    # the scope object and the result to be added to `@buffer`.
    #
    # If `opts[:preserve_script]` is true, Haml::Helpers#find_and_flatten is run on
    # the result before it is added to `@buffer`
    def push_script(text, opts = {})
      raise SyntaxError.new("There's no Ruby code for = to evaluate.") if text.empty?
      text = handle_ruby_multiline(text)
      return if options[:suppress_eval]
      opts[:escape_html] = options[:escape_html] if opts[:escape_html].nil?

      args = %w[preserve_script in_tag preserve_tag escape_html nuke_inner_whitespace]
      args.map! {|name| opts[name.to_sym]}
      args << !block_opened? << @options[:ugly]

      no_format = @options[:ugly] &&
        !(opts[:preserve_script] || opts[:preserve_tag] || opts[:escape_html])
      output_expr = "(#{text}\n)"
      static_method = "_hamlout.#{static_method_name(:format_script, *args)}"

      # Prerender tabulation unless we're in a tag
      push_merged_text '' unless opts[:in_tag]

      unless block_opened?
        @to_merge << [:script, no_format ? "#{text}\n" : "#{static_method}(#{output_expr});"]
        concat_merged_text("\n") unless opts[:in_tag] || opts[:nuke_inner_whitespace]
        @newlines -= 1
        return
      end

      flush_merged_text

      push_silent "haml_temp = #{text}"
      newline_now
      push_and_tabulate([:loud, "_hamlout.buffer << #{no_format ? "haml_temp.to_s;" : "#{static_method}(haml_temp);"}",
        !(opts[:in_tag] || opts[:nuke_inner_whitespace] || @options[:ugly])])
    end

    # Causes `text` to be evaluated, and Haml::Helpers#find_and_flatten
    # to be run on it afterwards.
    def push_flat_script(text, options = {})
      flush_merged_text

      raise SyntaxError.new("There's no Ruby code for ~ to evaluate.") if text.empty?
      push_script(text, options.merge(:preserve_script => true))
    end

    def start_haml_comment
      return unless block_opened?

      @haml_comment = true
      push_and_tabulate([:haml_comment])
    end

    # Closes the most recent item in `@to_close_stack`.
    def close
      tag, *rest = @to_close_stack.pop
      send("close_#{tag}", *rest)
    end

    # Puts a line in `@precompiled` that will add the closing tag of
    # the most recently opened tag.
    def close_element(value)
      tag, nuke_outer_whitespace, nuke_inner_whitespace = value
      @output_tabs -= 1 unless nuke_inner_whitespace
      @template_tabs -= 1
      rstrip_buffer! if nuke_inner_whitespace
      push_merged_text("</#{tag}>" + (nuke_outer_whitespace ? "" : "\n"),
                       nuke_inner_whitespace ? 0 : -1, !nuke_inner_whitespace)
      @dont_indent_next_line = nuke_outer_whitespace
    end

    # Closes a Ruby block.
    def close_script(_1, _2, push_end = true)
      push_silent("end", true) if push_end
      @template_tabs -= 1
    end

    # Closes a comment.
    def close_comment(has_conditional)
      @output_tabs -= 1
      @template_tabs -= 1
      close_tag = has_conditional ? "<![endif]-->" : "-->"
      push_text(close_tag, -1)
    end

    # Closes a loud Ruby block.
    def close_loud(command, add_newline, push_end = true)
      push_silent('end', true) if push_end
      @precompiled << command
      @template_tabs -= 1
      concat_merged_text("\n") if add_newline
    end

    # Closes a filtered block.
    def close_filtered(filter)
      filter.internal_compile(self, @filter_buffer)
      @flat = false
      @flat_spaces = nil
      @filter_buffer = nil
      @template_tabs -= 1
    end

    def close_haml_comment
      @haml_comment = false
      @template_tabs -= 1
    end

    def close_nil(*args)
      @template_tabs -= 1
    end

    # This is a class method so it can be accessed from {Haml::Helpers}.
    #
    # Iterates through the classes and ids supplied through `.`
    # and `#` syntax, and returns a hash with them as attributes,
    # that can then be merged with another attributes hash.
    def self.parse_class_and_id(list)
      attributes = {}
      list.scan(/([#.])([-:_a-zA-Z0-9]+)/) do |type, property|
        case type
        when '.'
          if attributes['class']
            attributes['class'] += " "
          else
            attributes['class'] = ""
          end
          attributes['class'] += property
        when '#'; attributes['id'] = property
        end
      end
      attributes
    end

    def parse_static_hash(text)
      attributes = {}
      scanner = StringScanner.new(text)
      scanner.scan(/\s+/)
      until scanner.eos?
        return unless key = scanner.scan(LITERAL_VALUE_REGEX)
        return unless scanner.scan(/\s*=>\s*/)
        return unless value = scanner.scan(LITERAL_VALUE_REGEX)
        return unless scanner.scan(/\s*(?:,|$)\s*/)
        attributes[eval(key).to_s] = eval(value).to_s
      end
      text.count("\n").times { newline }
      attributes
    end

    # This is a class method so it can be accessed from Buffer.
    def self.build_attributes(is_html, attr_wrapper, attributes = {})
      quote_escape = attr_wrapper == '"' ? """ : "'"
      other_quote_char = attr_wrapper == '"' ? "'" : '"'

      if attributes['data'].is_a?(Hash)
        attributes = attributes.dup
        attributes =
          Haml::Util.map_keys(attributes.delete('data')) {|name| "data-#{name}"}.merge(attributes)
      end

      result = attributes.collect do |attr, value|
        next if value.nil?

        value = filter_and_join(value, ' ') if attr == 'class'
        value = filter_and_join(value, '_') if attr == 'id'

        if value == true
          next " #{attr}" if is_html
          next " #{attr}=#{attr_wrapper}#{attr}#{attr_wrapper}"
        elsif value == false
          next
        end

        value = Haml::Helpers.preserve(Haml::Helpers.escape_once(value.to_s))
        # We want to decide whether or not to escape quotes
        value.gsub!('"', '"')
        this_attr_wrapper = attr_wrapper
        if value.include? attr_wrapper
          if value.include? other_quote_char
            value = value.gsub(attr_wrapper, quote_escape)
          else
            this_attr_wrapper = other_quote_char
          end
        end
        " #{attr}=#{this_attr_wrapper}#{value}#{this_attr_wrapper}"
      end
      result.compact.sort.join
    end

    def self.filter_and_join(value, separator)
      return "" if value == ""
      value = [value] unless value.is_a?(Array)
      value = value.flatten.collect {|item| item ? item.to_s : nil}.compact.join(separator)
      return !value.empty? && value
    end

    def prerender_tag(name, self_close, attributes)
      attributes_string = Precompiler.build_attributes(html?, @options[:attr_wrapper], attributes)
      "<#{name}#{attributes_string}#{self_close && xhtml? ? ' /' : ''}>"
    end

    # Parses a line into tag_name, attributes, attributes_hash, object_ref, action, value
    def parse_tag(line)
      raise SyntaxError.new("Invalid tag: \"#{line}\".") unless match = line.scan(/%([-:\w]+)([-:\w\.\#]*)(.*)/)[0]
      tag_name, attributes, rest = match
      new_attributes_hash = old_attributes_hash = last_line = object_ref = nil
      attributes_hashes = []
      while rest
        case rest[0]
        when ?{
          break if old_attributes_hash
          old_attributes_hash, rest, last_line = parse_old_attributes(rest)
          attributes_hashes << [:old, old_attributes_hash]
        when ?(
          break if new_attributes_hash
          new_attributes_hash, rest, last_line = parse_new_attributes(rest)
          attributes_hashes << [:new, new_attributes_hash]
        when ?[
          break if object_ref
          object_ref, rest = balance(rest, ?[, ?])
        else; break
        end
      end

      if rest
        nuke_whitespace, action, value = rest.scan(/(<>|><|[><])?([=\/\~&!])?(.*)?/)[0]
        nuke_whitespace ||= ''
        nuke_outer_whitespace = nuke_whitespace.include? '>'
        nuke_inner_whitespace = nuke_whitespace.include? '<'
      end

      value = value.to_s.strip
      [tag_name, attributes, attributes_hashes, object_ref, nuke_outer_whitespace,
       nuke_inner_whitespace, action, value, last_line || @index]
    end

    def parse_old_attributes(line)
      line = line.dup
      last_line = @index

      begin
        attributes_hash, rest = balance(line, ?{, ?})
      rescue SyntaxError => e
        if line.strip[-1] == ?, && e.message == "Unbalanced brackets."
          line << "\n" << @next_line.text
          last_line += 1
          next_line
          retry
        end

        raise e
      end

      attributes_hash = attributes_hash[1...-1] if attributes_hash
      return attributes_hash, rest, last_line
    end

    def parse_new_attributes(line)
      line = line.dup
      scanner = StringScanner.new(line)
      last_line = @index
      attributes = {}

      scanner.scan(/\(\s*/)
      loop do
        name, value = parse_new_attribute(scanner)
        break if name.nil?

        if name == false
          text = (Haml::Shared.balance(line, ?(, ?)) || [line]).first
          raise Haml::SyntaxError.new("Invalid attribute list: #{text.inspect}.", last_line - 1)
        end
        attributes[name] = value
        scanner.scan(/\s*/)

        if scanner.eos?
          line << " " << @next_line.text
          last_line += 1
          next_line
          scanner.scan(/\s*/)
        end
      end

      static_attributes = {}
      dynamic_attributes = "{"
      attributes.each do |name, (type, val)|
        if type == :static
          static_attributes[name] = val
        else
          dynamic_attributes << inspect(name) << " => " << val << ","
        end
      end
      dynamic_attributes << "}"
      dynamic_attributes = nil if dynamic_attributes == "{}"

      return [static_attributes, dynamic_attributes], scanner.rest, last_line
    end

    def parse_new_attribute(scanner)
      unless name = scanner.scan(/[-:\w]+/)
        return if scanner.scan(/\)/)
        return false
      end

      scanner.scan(/\s*/)
      return name, [:static, true] unless scanner.scan(/=/) #/end

      scanner.scan(/\s*/)
      unless quote = scanner.scan(/["']/)
        return false unless var = scanner.scan(/(@@?|\$)?\w+/)
        return name, [:dynamic, var]
      end

      re = /((?:\\.|\#(?!\{)|[^#{quote}\\#])*)(#{quote}|#\{)/
      content = []
      loop do
        return false unless scanner.scan(re)
        content << [:str, scanner[1].gsub(/\\(.)/, '\1')]
        break if scanner[2] == quote
        content << [:ruby, balance(scanner, ?{, ?}, 1).first[0...-1]]
      end

      return name, [:static, content.first[1]] if content.size == 1
      return name, [:dynamic,
        '"' + content.map {|(t, v)| t == :str ? inspect(v)[1...-1] : "\#{#{v}}"}.join + '"']
    end

    # Parses a line that will render as an XHTML tag, and adds the code that will
    # render that tag to `@precompiled`.
    def render_tag(line)
      tag_name, attributes, attributes_hashes, object_ref, nuke_outer_whitespace,
        nuke_inner_whitespace, action, value, last_line = parse_tag(line)

      raise SyntaxError.new("Illegal element: classes and ids must have values.") if attributes =~ /[\.#](\.|#|\z)/

      # Get rid of whitespace outside of the tag if we need to
      rstrip_buffer! if nuke_outer_whitespace

      preserve_tag = options[:preserve].include?(tag_name)
      nuke_inner_whitespace ||= preserve_tag
      preserve_tag &&= !options[:ugly]

      escape_html = (action == '&' || (action != '!' && @options[:escape_html]))

      case action
      when '/'; self_closing = true
      when '~'; parse = preserve_script = true
      when '='
        parse = true
        if value[0] == ?=
          value = unescape_interpolation(value[1..-1].strip, :escape_html => escape_html)
          escape_html = false
        end
      when '&', '!'
        if value[0] == ?= || value[0] == ?~
          parse = true
          preserve_script = (value[0] == ?~)
          if value[1] == ?=
            value = unescape_interpolation(value[2..-1].strip, :escape_html => escape_html)
            escape_html = false
          else
            value = value[1..-1].strip
          end
        elsif contains_interpolation?(value)
          value = unescape_interpolation(value, :escape_html => escape_html)
          parse = true
          escape_html = false
        end
      else
        if contains_interpolation?(value)
          value = unescape_interpolation(value, :escape_html => escape_html)
          parse = true
          escape_html = false
        end
      end

      if parse && @options[:suppress_eval]
        parse = false
        value = ''
      end

      object_ref = "nil" if object_ref.nil? || @options[:suppress_eval]

      attributes = Precompiler.parse_class_and_id(attributes)
      attributes_hashes.map! do |syntax, attributes_hash|
        if syntax == :old
          static_attributes = parse_static_hash(attributes_hash)
          attributes_hash = nil if static_attributes || @options[:suppress_eval]
        else
          static_attributes, attributes_hash = attributes_hash
        end
        Buffer.merge_attrs(attributes, static_attributes) if static_attributes
        attributes_hash
      end.compact!

      raise SyntaxError.new("Illegal nesting: nesting within a self-closing tag is illegal.", @next_line.index) if block_opened? && self_closing
      raise SyntaxError.new("There's no Ruby code for #{action} to evaluate.", last_line - 1) if parse && value.empty?
      raise SyntaxError.new("Self-closing tags can't have content.", last_line - 1) if self_closing && !value.empty?

      if block_opened? && !value.empty? && !is_ruby_multiline?(value)
        raise SyntaxError.new("Illegal nesting: content can't be both given on the same line as %#{tag_name} and nested within it.", @next_line.index)
      end

      self_closing ||= !!(!block_opened? && value.empty? && @options[:autoclose].any? {|t| t === tag_name})
      value = nil if value.empty? && (block_opened? || self_closing)

      dont_indent_next_line =
        (nuke_outer_whitespace && !block_opened?) ||
        (nuke_inner_whitespace && block_opened?)

      # Check if we can render the tag directly to text and not process it in the buffer
      if object_ref == "nil" && attributes_hashes.empty? && !preserve_script
        tag_closed = !block_opened? && !self_closing && !parse

        open_tag  = prerender_tag(tag_name, self_closing, attributes)
        if tag_closed
          open_tag << "#{value}</#{tag_name}>"
          open_tag << "\n" unless nuke_outer_whitespace
        else
          open_tag << "\n" unless parse || nuke_inner_whitespace || (self_closing && nuke_outer_whitespace)
        end

        push_merged_text(open_tag, tag_closed || self_closing || nuke_inner_whitespace ? 0 : 1,
                         !nuke_outer_whitespace)

        @dont_indent_next_line = dont_indent_next_line
        return if tag_closed
      else
        flush_merged_text
        content = parse ? 'nil' : inspect(value)
        if attributes_hashes.empty?
          attributes_hashes = ''
        elsif attributes_hashes.size == 1
          attributes_hashes = ", #{attributes_hashes.first}"
        else
          attributes_hashes = ", (#{attributes_hashes.join(").merge(")})"
        end

        args = [tag_name, self_closing, !block_opened?, preserve_tag, escape_html,
                attributes, nuke_outer_whitespace, nuke_inner_whitespace
               ].map {|v| inspect(v)}.join(', ')
        push_silent "_hamlout.open_tag(#{args}, #{object_ref}, #{content}#{attributes_hashes})"
        @dont_tab_up_next_text = @dont_indent_next_line = dont_indent_next_line
      end

      return if self_closing

      if value.nil?
        push_and_tabulate([:element, [tag_name, nuke_outer_whitespace, nuke_inner_whitespace]])
        @output_tabs += 1 unless nuke_inner_whitespace
        return
      end

      if parse
        push_script(value, :preserve_script => preserve_script, :in_tag => true,
          :preserve_tag => preserve_tag, :escape_html => escape_html,
          :nuke_inner_whitespace => nuke_inner_whitespace)
        concat_merged_text("</#{tag_name}>" + (nuke_outer_whitespace ? "" : "\n"))
      end
    end

    # Renders a line that creates an XHTML tag and has an implicit div because of
    # `.` or `#`.
    def render_div(line)
      render_tag('%div' + line)
    end

    # Renders an XHTML comment.
    def render_comment(line)
      conditional, line = balance(line, ?[, ?]) if line[0] == ?[
      line.strip!
      conditional << ">" if conditional

      if block_opened? && !line.empty?
        raise SyntaxError.new('Illegal nesting: nesting within a tag that already has content is illegal.', @next_line.index)
      end

      open = "<!--#{conditional}"

      # Render it statically if possible
      unless line.empty?
        return push_text("#{open} #{line} #{conditional ? "<![endif]-->" : "-->"}")
      end

      push_text(open, 1)
      @output_tabs += 1
      push_and_tabulate([:comment, !conditional.nil?])
      unless line.empty?
        push_text(line)
        close
      end
    end

    # Renders an XHTML doctype or XML shebang.
    def render_doctype(line)
      raise SyntaxError.new("Illegal nesting: nesting within a header command is illegal.", @next_line.index) if block_opened?
      doctype = text_for_doctype(line)
      push_text doctype if doctype
    end

    def text_for_doctype(text)
      text = text[3..-1].lstrip.downcase
      if text.index("xml") == 0
        return nil if html?
        wrapper = @options[:attr_wrapper]
        return "<?xml version=#{wrapper}1.0#{wrapper} encoding=#{wrapper}#{text.split(' ')[1] || "utf-8"}#{wrapper} ?>"
      end

      if html5?
        '<!DOCTYPE html>'
      else
        version, type = text.scan(DOCTYPE_REGEX)[0]

        if xhtml?
          if version == "1.1"
            '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'
          elsif version == "5"
            '<!DOCTYPE html>'
          else
            case type
            when "strict";   '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
            when "frameset"; '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'
            when "mobile";   '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'
            when "rdfa";     '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">'
            when "basic";    '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">'
            else             '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
            end
          end

        elsif html4?
          case type
          when "strict";   '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'
          when "frameset"; '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'
          else             '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'
          end
        end
      end
    end

    # Starts a filtered block.
    def start_filtered(name)
      raise Error.new("Invalid filter name \":#{name}\".") unless name =~ /^\w+$/
      raise Error.new("Filter \"#{name}\" is not defined.") unless filter = Filters.defined[name]

      push_and_tabulate([:filtered, filter])
      @flat = true
      @filter_buffer = String.new

      # If we don't know the indentation by now, it'll be set in Line#tabs
      @flat_spaces = @indentation * @template_tabs if @indentation
    end

    def raw_next_line
      text = @template.shift
      return unless text

      index = @template_index
      @template_index += 1

      return text, index
    end

    def next_line
      text, index = raw_next_line
      return unless text

      # :eod is a special end-of-document marker
      line =
        if text == :eod
          Line.new '-#', '-#', '-#', index, self, true
        else
          Line.new text.strip, text.lstrip.chomp, text, index, self, false
        end

      # `flat?' here is a little outdated,
      # so we have to manually check if either the previous or current line
      # closes the flat block,
      # as well as whether a new block is opened
      @line.tabs if @line
      unless (flat? && !closes_flat?(line) && !closes_flat?(@line)) ||
          (@line && @line.text[0] == ?: && line.full =~ %r[^#{@line.full[/^\s+/]}\s])
        if line.text.empty?
          newline
          return next_line
        end

        handle_multiline(line)
      end

      @next_line = line
    end

    def closes_flat?(line)
      line && !line.text.empty? && line.full !~ /^#{@flat_spaces}/
    end

    def un_next_line(line)
      @template.unshift line
      @template_index -= 1
    end

    def handle_multiline(line)
      return unless is_multiline?(line.text)
      line.text.slice!(-1)
      while new_line = raw_next_line.first
        break if new_line == :eod
        newline and next if new_line.strip.empty?
        break unless is_multiline?(new_line.strip)
        line.text << new_line.strip[0...-1]
        newline
      end
      un_next_line new_line
      resolve_newlines
    end

    # Checks whether or not +line+ is in a multiline sequence.
    def is_multiline?(text)
      text && text.length > 1 && text[-1] == MULTILINE_CHAR_VALUE && text[-2] == ?\s
    end

    def handle_ruby_multiline(text)
      text = text.rstrip
      return text unless is_ruby_multiline?(text)
      un_next_line @next_line.full
      begin
        new_line = raw_next_line.first
        break if new_line == :eod
        newline and next if new_line.strip.empty?
        text << " " << new_line.strip
        newline
      end while is_ruby_multiline?(new_line.strip)
      next_line
      resolve_newlines
      text
    end

    def is_ruby_multiline?(text)
      text && text.length > 1 && text[-1] == ?, && text[-2] != ?? && text[-3..-2] != "?\\"
    end

    def contains_interpolation?(str)
      str.include?('#{')
    end

    def unescape_interpolation(str, opts = {})
      res = ''
      rest = Haml::Shared.handle_interpolation inspect(str) do |scan|
        escapes = (scan[2].size - 1) / 2
        res << scan.matched[0...-3 - escapes]
        if escapes % 2 == 1
          res << '#{'
        else
          content = eval('"' + balance(scan, ?{, ?}, 1)[0][0...-1] + '"')
          content = "Haml::Helpers.html_escape((#{content}))" if opts[:escape_html]
          res << '#{' + content + "}"# Use eval to get rid of string escapes
        end
      end
      res + rest
    end

    def balance(*args)
      res = Haml::Shared.balance(*args)
      return res if res
      raise SyntaxError.new("Unbalanced brackets.")
    end

    def block_opened?
      !flat? && @next_line.tabs > @line.tabs
    end

    # Pushes value onto `@to_close_stack` and increases
    # `@template_tabs`.
    def push_and_tabulate(value)
      @to_close_stack.push(value)
      @template_tabs += 1
    end

    def flat?
      @flat
    end

    def newline
      @newlines += 1
    end

    def newline_now
      @precompiled << "\n"
      @newlines -= 1
    end

    def resolve_newlines
      return unless @newlines > 0
      @to_merge << [:newlines, @newlines]
      @newlines = 0
    end

    # Get rid of and whitespace at the end of the buffer
    # or the merged text
    def rstrip_buffer!(index = -1)
      last = @to_merge[index]
      if last.nil?
        push_silent("_hamlout.rstrip!", false)
        @dont_tab_up_next_text = true
        return
      end

      case last.first
      when :text
        last[1].rstrip!
        if last[1].empty?
          @to_merge.slice! index
          rstrip_buffer! index
        end
      when :script
        last[1].gsub!(/\(haml_temp, (.*?)\);$/, '(haml_temp.rstrip, \1);')
        rstrip_buffer! index - 1
      when :newlines
        rstrip_buffer! index - 1
      else
        raise SyntaxError.new("[HAML BUG] Undefined entry in Haml::Precompiler@to_merge.")
      end
    end
  end
end


text:
package com.ider.launcherpackage.launcher;

import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;

/**
 * Created by ider-eric on 2017/2/22.
 */
@Entity
public class PackageHolder {

    @Id(autoincrement = true)
    private Long id;
    private String packageName;
    private String tag;

    @Generated(hash = 1602000662)
    public PackageHolder(Long id, String packageName, String tag) {
        this.id = id;
        this.packageName = packageName;
        this.tag = tag;
    }

    public PackageHolder(String packageName, String tag) {
        this.packageName = packageName;
        this.tag = tag;
    }

    @Generated(hash = 448922367)
    public PackageHolder() {
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    public String getPackageName() {
        return this.packageName;
    }

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

}

redpajama_set_name: RedPajamaGithub


text:
module.exports = function isAdmin (req, res, next) {

  //user be a guest, yo
  if (req.session.user == undefined) {
    return res.redirect('/guestReminder');
  }
  var userId = req.session.user.id;

  Role
  .findOneByUserId(userId)
  .exec( function foundUser (err, user) {

    if (err) return next(err);

    //The user has a role omfg

    if (role.parent < 4) return res.redirect(req.redirect);

    next();
  });

}


text:
package it.cnr.isti.melampo.tools;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class AdHocMetadataMaker {

	public static void main(String[] args) {
		if (args.length != 1) {
			usage();
			return;
		}
		File imgDir = new File(args[0]);
		if (imgDir.isDirectory()) {
			AdHocMetadataMaker extractor = new AdHocMetadataMaker();
			extractor.recursiveDirClassification(imgDir);
		}
		else {
			usage();
			return;
		}

	}

	private String extractData(File htmlFile) throws IOException {
		StringBuilder metadata = new StringBuilder();

		BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(htmlFile), "UTF8"));
		// 		BufferedReader reader = new BufferedReader(new FileReader(htmlFile));

		String line = null;
		boolean isMetadata = false;
		while((line = reader.readLine()) != null) {
			line = line.trim();
			if (line.equals("")) {
				isMetadata = true;
			} else if (isMetadata == true && line.equals("	")) {
				isMetadata = false;
			}
			if (isMetadata == true) {
				line = line.replaceFirst("]*>", "\n");
				line = line.replaceFirst("]*>", "=");
				line = line.replaceFirst(":=", "=");
				line = line.replaceAll("<[^>]*>", "");
				line = line.replaceAll(" - ", ";");
				line = line.replaceAll(" ", "");
				metadata.append(line);
			}
		}
		return metadata.toString();
	}

	private void recursiveDirClassification(File testDir) {
        System.out.println("evaluating folder: " + testDir.getPath());
        // retrieve all files in testDir dir
        File[] dirFiles = testDir.listFiles();
        // number of files
        int numFiles = dirFiles.length;
        int startIndex = 0;

        int numImgFiles = 0;

        // index
        for (int index = startIndex; index < numFiles; index++) {
            File imgFile = null;

            if (dirFiles[index].isDirectory()) {
                recursiveDirClassification(dirFiles[index]);
            } else {
                    imgFile = dirFiles[index];
                    String features;
    				try {
    					features = extractData(imgFile);
        				Tools.string2File(features, new File("D:/demo/adhoc/metadatatxt/" + imgFile.getName().substring(0, imgFile.getName().lastIndexOf(".")) +  ".txt"));
        				System.out.println("img file " + imgFile.getPath());
                        numImgFiles++;
    				} catch (IOException e) {
    					System.out.println("error saving features file " + "D:/demo/adhoc/metadatatxt/" + imgFile.getName().substring(0, imgFile.getPath().lastIndexOf(".")) +  ".txt");
						e.printStackTrace();
					}
                    }
                }
        System.out.println("evaluated " +numFiles + " files");
            }

	private static void usage() {
		System.out.println("Usage: AdhocMetadataMaker img_file_dir [-r]");

	}
}


text:
<?php

/**
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 *
 * @author otto <otto@valjakko.net>
 * @author Teemu Mattila <ghcsystems@gmail.com>
 * @author Sami Olmari <sami@olmari.fi>
 * @author Jussi Takala <jussi.takala@live.fi>
 */
$lang['menu']                  = 'Käyttäjähallinta';
$lang['noauth']                = '(autentikointi ei ole käytössä)';
$lang['nosupport']             = '(käyttäjähallinta ei ole tuettu)';
$lang['badauth']               = 'Viallinen autentikointimenetelmä';
$lang['user_id']               = 'Käyttäjä';
$lang['user_pass']             = 'Salasana';
$lang['user_name']             = 'Oikea nimi';
$lang['user_mail']             = 'Sähköposti';
$lang['user_groups']           = 'Ryhmät';
$lang['field']                 = 'Kenttä';
$lang['value']                 = 'Arvo';
$lang['add']                   = 'Lisää';
$lang['delete']                = 'Poista';
$lang['delete_selected']       = 'Poista valittu';
$lang['edit']                  = 'Muokkaa';
$lang['edit_prompt']           = 'Muokkaa ryhmää';
$lang['modify']                = 'Tallenna muutokset';
$lang['search']                = 'Hae';
$lang['search_prompt']         = 'Tee haku';
$lang['clear']                 = 'Tyhjennä hakusuodatin';
$lang['filter']                = 'Suodatin';
$lang['import']                = 'Tuo uusia käyttäjiä';
$lang['line']                  = 'Rivi nro.';
$lang['error']                 = 'Vikailmoitus';
$lang['summary']               = 'Näytetään käyttäjät %1$d-%2$d / %3$d löytynyttä. %4$d käyttäjää yhteensä.';
$lang['nonefound']             = 'Ei löytynyt käyttäjiä. %d käyttäjää yhteensä.';
$lang['delete_ok']             = '%d käyttäjää poistettu';
$lang['delete_fail']           = '%d poistoa epäonnistui';
$lang['update_ok']             = 'Käyttäjän päivitys onnistui';
$lang['update_fail']           = 'Käyttäjän päivitys epäonnistui';
$lang['update_exists']         = 'Käyttäjän nimen vaihto epäonnistui. Nimi (%s) on jo olemassa (muut muutokset onnistuivat)';
$lang['start']                 = 'alku';
$lang['prev']                  = 'edellinen';
$lang['next']                  = 'seuraava';
$lang['last']                  = 'viimeinen';
$lang['edit_usermissing']      = 'Valittua käyttäjää ei löytynyt. Käyttäjä on voitu päivittää tai poistaa muualta.';
$lang['user_notify']           = 'Tiedota käyttäjälle';
$lang['note_notify']           = 'Tiedotus lähetetään vain, jos käyttäjälle on määritelty uusi salasana.';
$lang['note_group']            = 'Uudelle käyttäjälle määritellään oletusryhmä (%s), jos ryhmää ei erikseen määritellä.';
$lang['note_pass']             = 'Salasana luodaan automaattisesti, mikäli kenttä jätetään tyhjäksi ja jos käyttäjän tiedotus on päällä.';
$lang['add_ok']                = 'Käyttäjä lisätty onnistuneesti';
$lang['add_fail']              = 'Käyttäjän lisäys epäonnistui';
$lang['notify_ok']             = 'Ilmoitus sähköpostilla lähetetty';
$lang['notify_fail']           = 'Ilmoitusta sähköpostilla ei voitu lähettää';
$lang['import_error_baduserid'] = 'Käyttäjätunnus puuttuu';
$lang['import_error_badname']  = 'Epäkelpo nimi';
$lang['import_error_badmail']  = 'Epäkelpo sähköpostiosoite';
$lang['import_error_upload']   = 'Tuonti epäonnistui. CSV-tiedostoa ei voitu ladata tai se on tyhjä.';
$lang['import_error_readfail'] = 'Tuonti epäonnistui. Ladattua tiedostoa ei voida lukea.';
$lang['import_error_create']   = 'Käyttäjää ei voida luoda.';


text:
(function () {
    'use strict';

    var gulp         = require('gulp'),
        config       = require('../config'),
        handleErrors = require('../util/handle-errors'),
        gulpIf       = require('gulp-if'),
        sourcemaps   = require('gulp-sourcemaps'),
        scssLint     = require('gulp-scss-lint'),
        sass         = require('gulp-sass'),
        autoprefixer = require('gulp-autoprefixer'),
        minifyCss    = require('gulp-minify-css'),
        browserSync  = require('browser-sync'),
        plumber      = require('gulp-plumber');

    gulp.task('sass', ['images'], function () {
        return gulp
            .src(config.sass.src)
            .pipe(plumber())
            .pipe(gulpIf(config.debug, sourcemaps.init()))
            .pipe(scssLint())
            .pipe(sass(config.sass.settings))
            .on('error', handleErrors)
            .pipe(autoprefixer(config.autoprefixer))
            .pipe(minifyCss({
                keepSpecialComments: '*'
            }))
            .pipe(gulpIf(config.debug, sourcemaps.write()))
            .pipe(gulp.dest(config.sass.dest))
            .pipe(browserSync.reload({
                stream: true
            }));
    });
})();


text:
from __future__ import unicode_literals

from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [
        ('addons_wiki', '0010_migrate_node_wiki_pages'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='nodewikipage',
            name='node',
        ),
        migrations.RemoveField(
            model_name='nodewikipage',
            name='user',
        ),
        migrations.DeleteModel(
            name='NodeWikiPage',
        ),
    ]


text:
/*	$OpenBSD: openfirm.h,v 1.2 1997/11/07 08:07:24 niklas Exp $	*/
/*	$NetBSD: openfirm.h,v 1.1 1996/09/30 16:35:10 ws Exp $	*/

/*
 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
 * Copyright (C) 1995, 1996 TooLs GmbH.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by TooLs GmbH.
 * 4. The name of TooLs GmbH may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * Prototypes for OpenFirmware Interface Routines
 */

#include <sys/param.h>
#include <sys/device.h>

int openfirmware __P((void *));

extern char *OF_buf;

int OF_peer __P((int phandle));
int OF_child __P((int phandle));
int OF_parent __P((int phandle));
int OF_instance_to_package __P((int ihandle));
int OF_getprop __P((int handle, char *prop, void *buf, int buflen));
int OF_finddevice __P((char *name));
int OF_instance_to_path __P((int ihandle, char *buf, int buflen));
int OF_package_to_path __P((int phandle, char *buf, int buflen));
int OF_call_method_1 __P((char *method, int ihandle, int nargs, ...));
int OF_call_method __P((char *method, int ihandle, int nargs, int nreturns, ...));
int OF_open __P((char *dname));
void OF_close __P((int handle));
int OF_read __P((int handle, void *addr, int len));
int OF_write __P((int handle, void *addr, int len));
int OF_seek __P((int handle, u_quad_t pos));
void OF_boot __P((char *bootspec)) __attribute__((__noreturn__));
void OF_enter __P((void));
void OF_exit __P((void)) __attribute__((__noreturn__));
void (*OF_set_callback __P((void (*newfunc)(void *)))) ();

/*
 * Some generic routines for OpenFirmware handling.
 */
int ofnmmatch __P((char *cp1, char *cp2));

/*
 * Generic OpenFirmware probe argument.
 * This is how all probe structures must start
 * in order to support generic OpenFirmware device drivers.
 */
struct ofprobe {
	int phandle;
	/*
	 * Special unit field for disk devices.
	 * This is a KLUDGE to work around the fact that OpenFirmware
	 * doesn't probe the scsi bus completely.
	 * YES, I THINK THIS IS A BUG IN THE OPENFIRMWARE DEFINITION!!!	XXX
	 * See also ofdisk.c.
	 */
	int unit;
};

/*
 * The softc structure for devices we might be booted from (i.e. we might
 * want to set root/swap to) needs to start with these fields:		XXX
 */
struct ofb_softc {
	struct device sc_dev;
	int sc_phandle;
	int sc_unit;		/* Might be missing for non-disk devices */
};


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Generator.ExtensionMethods;

namespace Generator.AstNodes {
	public class DictionaryMember {
		private DictionaryMember() {}

		public WebIDLType Type { get; private set; }
		public string Name { get; private set; }
		public Value Default { get; private set; }
		public IReadOnlyList<ExtendedAttribute> ExtendedAttributes { get; private set; }

		public static DictionaryMember Create(WebIDLType type, string name, Value @default, IEnumerable<ExtendedAttribute> extendedAttributes) {
			return new DictionaryMember { Type = type, Name = name, Default = @default, ExtendedAttributes = extendedAttributes.AsReadOnlySafe() };
		}
	}
}


text:
#include <aws/rds/model/CreateEventSubscriptionRequest.h>
#include <aws/core/utils/StringUtils.h>
#include <aws/core/utils/memory/stl/AWSStringStream.h>

using namespace Aws::RDS::Model;
using namespace Aws::Utils;

CreateEventSubscriptionRequest::CreateEventSubscriptionRequest() :
    m_subscriptionNameHasBeenSet(false),
    m_snsTopicArnHasBeenSet(false),
    m_sourceTypeHasBeenSet(false),
    m_eventCategoriesHasBeenSet(false),
    m_sourceIdsHasBeenSet(false),
    m_enabled(false),
    m_enabledHasBeenSet(false)
{
}

Aws::String CreateEventSubscriptionRequest::SerializePayload() const
{
  Aws::StringStream ss;
  ss << "Action=CreateEventSubscription&";
  if(m_subscriptionNameHasBeenSet)
  {
    ss << "SubscriptionName=" << StringUtils::URLEncode(m_subscriptionName.c_str()) << "&";
  }
  if(m_snsTopicArnHasBeenSet)
  {
    ss << "SnsTopicArn=" << StringUtils::URLEncode(m_snsTopicArn.c_str()) << "&";
  }
  if(m_sourceTypeHasBeenSet)
  {
    ss << "SourceType=" << StringUtils::URLEncode(m_sourceType.c_str()) << "&";
  }
  if(m_eventCategoriesHasBeenSet)
  {
    unsigned eventCategoriesCount = 1;
    for(auto& item : m_eventCategories)
    {
      ss << "EventCategories.member." << eventCategoriesCount << "="
          << StringUtils::URLEncode(item.c_str()) << "&";
      eventCategoriesCount++;
    }
  }
  if(m_sourceIdsHasBeenSet)
  {
    unsigned sourceIdsCount = 1;
    for(auto& item : m_sourceIds)
    {
      ss << "SourceIds.member." << sourceIdsCount << "="
          << StringUtils::URLEncode(item.c_str()) << "&";
      sourceIdsCount++;
    }
  }
  if(m_enabledHasBeenSet)
  {
    ss << "Enabled=" << m_enabled << "&";
  }
  ss << "Version=2013-01-10";
  return ss.str();
}


text:
package com.microsoft.azure.management.kusto.v2018_09_07_preview;

import java.util.Collection;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.microsoft.rest.ExpandableStringEnum;

/**
 * Defines values for DataFormat.
 */
public final class DataFormat extends ExpandableStringEnum<DataFormat> {
    /** Static value MULTIJSON for DataFormat. */
    public static final DataFormat MULTIJSON = fromString("MULTIJSON");

    /** Static value JSON for DataFormat. */
    public static final DataFormat JSON = fromString("JSON");

    /** Static value CSV for DataFormat. */
    public static final DataFormat CSV = fromString("CSV");

    /**
     * Creates or finds a DataFormat from its string representation.
     * @param name a name to look for
     * @return the corresponding DataFormat
     */
    @JsonCreator
    public static DataFormat fromString(String name) {
        return fromString(name, DataFormat.class);
    }

    /**
     * @return known DataFormat values
     */
    public static Collection<DataFormat> values() {
        return values(DataFormat.class);
    }
}


text:
from __future__ import print_function
from napalm_base import get_network_driver
from getpass import getpass
from pprint import pprint

device1 = {
    'hostname': 'arista-p3.twb-tech.com',
    'username': 'interop',
    'password': getpass(),
    'optional_args': {},
}

driver = get_network_driver('eos')
napalm_conn = driver(**device1)

print()
print(">>>Test device open")
napalm_conn.open()

pprint(napalm_conn.get_facts())


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.8"/>
<title>Snowball: /home/superuser/Snowball/snowball/body/engine/encryption/encryption.h Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

Snowball
    1.0.1

Self copying porgram

Main Page

Namespaces

Files

          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

File List

File Members

 All Namespaces Files Functions

body

engine

encryption

encryption.h

Go to the documentation of this file.

    1 #ifndef ENCRYPTION_H

    2 #define ENCRYPTION_H

    3

    4 #include <fstream>

    5 #include <string>

    6 #include <iostream>

    7 #include <cstdio>

    8 #include <random>

    9 namespace engine {

   10 std::string encrypt_Decrypt(std::string toEncrypt, char key);

   11 char getRandom();

   12 } //namespace engine

   13 #endif

   14

   15

engine::getRandom

char getRandom()

Allows the user to get a random character.

Definition: encryption.cpp:25

engine::encrypt_Decrypt

std::string encrypt_Decrypt(std::string toEncrypt, char key)

This function allows the encryption and decryption of text.

Definition: encryption.cpp:12

engine

This namespace contains the components of Snowball's Polymorphic Engine.

Definition: encryption.cpp:5

<address class="footer">
Generated on Mon Apr 3 2017 21:04:06 for Snowball by

 1.8.8
</address>


text:
using z100emu.Core;
using z100emu.Ram;

namespace z100emu.Peripheral.Zenith
{
    public class ZenithMemControl : IPortDevice
    {
        private byte _byte = 0;
        private IRam _ram;
        private ZenithRom _rom;

        public ZenithMemControl(IRam ram, ZenithRom rom)
        {
            _ram = ram;
            _rom = rom;
        }

        public byte Read(int port) { return _byte; }
        public ushort Read16(int port) { return Read(port); }

        public void Write16(int port, ushort value) { Write(port, (byte) value); }

        public void Write(int port, byte value)
        {
            _byte = value;

            var ramConfig = value & 2;
            var romConfig = (value >> 2) & 2;

            _ram.ZeroParity = (value & (1 << 4)) == 0;
            var kill = (value & (1 << 5)) == 0;

            if (_ram.KillParity && !kill)
            {
                _ram.ClearParityError();
            }
            _ram.KillParity = kill;

            switch (ramConfig)
            {
                case 0:
                    _ram.RamConfig = RamConfig.Option0;
                    break;
                case 1:
                    _ram.RamConfig = RamConfig.Option1;
                    break;
                case 2:
                    _ram.RamConfig = RamConfig.Option2;
                    break;
                case 3:
                    _ram.RamConfig = RamConfig.Option3;
                    break;
            }

            switch (romConfig)
            {
                case 0:
                    _rom.RomConfig = RomConfig.Option0;
                    break;
                case 1:
                    _rom.RomConfig = RomConfig.Option1;
                    break;
                case 2:
                    _rom.RomConfig = RomConfig.Option2;
                    break;
                case 3:
                    _rom.RomConfig = RomConfig.Option3;
                    break;
            }
        }

        public int[] Ports => new int[] { 0xFC };
    }
}


text:
package intellij.haskell.psi.impl;

import java.util.List;
import org.jetbrains.annotations.*;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.util.PsiTreeUtil;
import static intellij.haskell.psi.HaskellTypes.*;
import intellij.haskell.psi.*;

public class HaskellFileHeaderImpl extends HaskellCompositeElementImpl implements HaskellFileHeader {

  public HaskellFileHeaderImpl(ASTNode node) {
    super(node);
  }

  public void accept(@NotNull HaskellVisitor visitor) {
    visitor.visitFileHeader(this);
  }

  public void accept(@NotNull PsiElementVisitor visitor) {
    if (visitor instanceof HaskellVisitor) accept((HaskellVisitor)visitor);
    else super.accept(visitor);
  }

  @Override
  @NotNull
  public List<HaskellPragma> getPragmaList() {
    return PsiTreeUtil.getChildrenOfTypeAsList(this, HaskellPragma.class);
  }

}


text:
from __future__ import absolute_import

from .base import Immutable

class Provider(Immutable):
    subsystem = "infra"
    endpoint = "/provider"
    is_namespaced = False

    @classmethod
    def _pk_key(cls):
        return 'name'

    def delete(self):
        raise AttributeError("'delete' is not supported in 'Provider'")

    def save(self):
        raise AttributeError("'save' is not supported in 'Provider'")


text:
use juniper::GraphQLInterface;

#[derive(GraphQLInterface)]
struct __Character {
    id: String,
}

fn main() {}


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<link rel="stylesheet" type="text/css" href="../../css/style.css">
	<link rel="icon" href="../../img/icon.png">
	<title>QRazyBox - Help Page</title>

QRazyBox Help

				<input type="text" placeholder="Search here...">

Help › Editor & Painter › Format Info Pattern

Format Info Pattern

As explained in the previous section, Format information pattern is module pattern that tell about current specification that being used by QR code, that is Error correction level and Mask Pattern.

		You can set Format information pattern by clicking the blue colored modules and you will be prompted with the dialog as shown below.

There are two ways to set Format info pattern. First, simply clicking on module one by one like using Painter. Second, you can select options that located under the modules to set values of Error correction level and Mask pattern and Format info pattern will automatically drawn by itself. These two ways will synchronize with each other automatically.

		Keep in mind, that Format info pattern only accept black and white color. Thus, grey color (damaged parts) cannot be drawn in here. Just leave it with white color if the actual module is missing or unknown.

		But, if the whole format info pattern is missing, you can use extension tools called Brute-force Format Info Pattern to automatically find the right pattern.

Format info pattern is shared in three location of QR code (top left, bottom left, and top right) and always located close to finder pattern. By setting only in one location, will automatically set the other two location.

			<button class="left" onclick="window.location='painter-basic-usage.html';">Prev : Painter Basic Usage</button>
			<button class="right" onclick="window.location='undo-redo-using-history.html';">Next : Undo/Redo Using History</button>


text:
// Copyright 2009 the Sputnik authors.  All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/**
* @name: S11.6.1_A4_T8;
* @section: 11.6.1, 11.6.3;
* @assertion: The result of an addition is determined using the rules of IEEE 754 double-precision arithmetics;
* @description: If the magnitude is too large to represent, the operation overflows and the result is then an infinity of appropriate sign;
*/

//CHECK#1
if (Number.MAX_VALUE + Number.MAX_VALUE !== Number.POSITIVE_INFINITY) {
  $ERROR('#1: Number.MAX_VALUE + Number.MAX_VALUE === Number.POSITIVE_INFINITY. Actual: ' + (Number.MAX_VALUE + Number.MAX_VALUE));
}

//CHECK#2
if (-Number.MAX_VALUE - Number.MAX_VALUE !== Number.NEGATIVE_INFINITY) {
  $ERROR('#2: -Number.MAX_VALUE - Number.MAX_VALUE === Number.NEGATIVE_INFINITY. Actual: ' + (-Number.MAX_VALUE - Number.MAX_VALUE));
}

//CHECK#3
if (1e+308 + 1e+308 !== Number.POSITIVE_INFINITY) {
  $ERROR('#3: 1e+308 + 1e+308 === Number.POSITIVE_INFINITY. Actual: ' + (1e+308 + 1e+308));
}

//CHECK#4
if (-8.99e+307 - 8.99e+307 !== Number.NEGATIVE_INFINITY) {
  $ERROR('#4: -8.99e+307 - 8.99e+307 === Number.NEGATIVE_INFINITY. Actual: ' + (-8.99e+307 - 8.99e+307));
}


text:
from toroid import app, database, tournament
from toroid.warrior import Warrior
from sys import exit, stdout
from getpass import getpass
from itertools import combinations
from sys import argv

# The -h and --help flags mean "only show usage/help"
if '-h' in argv or '--help' in argv:
    print("TOROID SUITE: RunTournament")
    print("This script runs a tournament on a Toroid database.")
    print("Options:")
    print("\t-h | --help  \tShow this help text.")
    print("\t--no_prezero \tDon't start with a blank slate of scores.")
    exit(0)

PREZERO = True
if '--no_prezero' in argv:
    PREZERO = False

# The number of rounds to run each head-to-head for.
ROUNDS = 50
if ROUNDS % 2 != 0:
    print("ROUNDS should be divisible by 2 (ROUNDS={}, consider {}, {})".format(ROUNDS, ROUNDS+1, ROUNDS-1))
    exit(3)

# This is the string used to format the results.
FMT_STRING = "{place:3}. {name:>24}  by {author:32}: {score:8}"

print("This script runs a tournament on a Toroid database.")
print("Scale your terminal so that this line fits on a single line:\n")
print(FMT_STRING.format(place=1,
                        name="Warrior Name",
                        author="Warrior K. Author",
                        score="1024"))
print("\nOnce you are certain that you are ready, enter your password:")

# Authenticate the command line user.
given = getpass("(characters will not appear) ")
#given = "password"
if app.config.get('ADMIN_PASSWORD', '') == given:
    print("Successfully authenticated!")
else:
    print("Access Denied.")
    exit(1)

# Pull everything from the database.
warriors = list(database.list_warriors())

if PREZERO:
    for warrior in warriors:
        warrior.score = 0

for pair in combinations(warriors, r=2):
    (w1score1, w2score1) = tournament.run_battle(pair[1], pair[0], rounds=int(ROUNDS/2))
    stdout.write(".")
    stdout.flush()
    (w1score2, w2score2) = tournament.run_battle(pair[0], pair[1], rounds=int(ROUNDS/2))
    stdout.write("o")
    stdout.flush()

    (w1score, w2score) = (w1score1 + w1score2, w2score1 + w2score2)

    pair[0].score += w1score
    pair[1].score += w2score

# Commit the warriors back to the database
print("\nCommitting the warriors back.")
for warrior in warriors:
    database.change_score_by_name(warrior.name, warrior.score)

print("The tournament is over!\n")
# The tournament has been run; sort the contestees

warriors.sort(key = lambda x: x.score, reverse=True)

# Display the warriors, that have been sorted
place = 1
last_score = 0
tied_so_far = 0
for w in warriors:
    if w.score < last_score:
        place += 1
    else:
        tied_so_far += 1

    last_score = w.score

    print(FMT_STRING.format(place=place,
                            name=w.name,
                            author=w.author,
                            score=w.score))


text:
#include <aws/iotwireless/model/GetWirelessGatewayCertificateRequest.h>
#include <aws/core/utils/json/JsonSerializer.h>

#include <utility>

using namespace Aws::IoTWireless::Model;
using namespace Aws::Utils::Json;
using namespace Aws::Utils;

GetWirelessGatewayCertificateRequest::GetWirelessGatewayCertificateRequest() :
    m_idHasBeenSet(false)
{
}

Aws::String GetWirelessGatewayCertificateRequest::SerializePayload() const
{
  return {};
}


text:
var expect = chai.expect;

describe("L.Illustrate.PointerHandle", function() {
	var map, pointer,
		_onVertexUpdate;

	beforeEach(function() {
		var anchor = new L.LatLng(41.7918, -87.6010);

		map = L.map(document.createElement('div')).setView([41.7896,-87.5996], 15);
		pointer = new L.Illustrate.Pointer(anchor, [
			new L.Point(0, 0),
			new L.Point(0, 10),
			new L.Point(0, 20),
			new L.Point(0, 40)
		]).addTo(map);
	});

	beforeEach(function() {
		_onVertexUpdate = sinon.spy(L.Illustrate.PointerHandle.prototype, "_onVertexUpdate");
	});

	beforeEach(function() {
		pointer.editing.enable();
	});

	afterEach(function() {
		_onVertexUpdate.restore();
	});

	describe("#_onVertexAdd", function() {
		it("Should add a vertex.", function() {
			var initialLength = pointer.getPoints().length,
				handle = pointer.editing._handles[1];

			expect(handle._type).to.equal('midpoint');
			handle.fire('drag', { target: handle });
			expect(handle._type).to.equal('vertex');

			expect(pointer.getPoints().length).to.equal(initialLength + 1);
		});

		it("Should not alter any other coordinates.", function() {
			var initialCoords = [].slice.call(pointer.getPoints(), 0),
				handle = pointer.editing._handles[1],
				coords;

			handle.fire('drag', { target: handle });

			coords = pointer.getPoints();

			expect(coords[0]).to.deep.equal(initialCoords[0]);
			expect(coords[2]).to.deep.equal(initialCoords[1]);
			expect(coords[3]).to.deep.equal(initialCoords[2]);
			expect(coords[4]).to.deep.equal(initialCoords[3]);
		});

		it("Should not leave any gaps in pointer.editing._handles", function() {
			var handles = pointer.editing._handles,
				initialHandlesLength = handles.length,
				handle = handles[1],
				i, l;

			for (i = 0, l = handles.length; i < length - 1; i++) {
				expect(handles[i + 1]._id).to.equal(handles[i]._id + 1);
			}

			handle.fire('drag', { target: handle });

			handles = pointer.editing._handles;
			expect(handles.length).to.equal(initialHandlesLength + 2);

			for (i = 0, l = handles.length; i < length; i++) {
				expect(handles[i]._id).to.equal(i);
			}
		});
	});

	describe("#_onVertexRemove", function() {
		it("Should only remove one vertex", function() {
			var initialCoords = [].slice.call(pointer.getPoints(), 0),
				handle = pointer.editing._handles[2],
				coords;

			handle.fire('click', { target: handle });

			coords = pointer.getPoints();
			expect(coords.length).to.equal(initialCoords.length - 1);
		});

		it("Should remove three handles from the map and add one back.", function() {
			var initialHandles = [].slice.call(pointer.editing._handles, 0),
				handle = initialHandles[2],
				handles;

			expect(handle._type).to.equal('vertex');
			handle.fire('click', { target: handle });

			handles = pointer.editing._handles;

			expect(handles.length).to.equal(initialHandles.length - 2);
		});

		it("Should not leave any gaps in pointer.editing._handles", function() {
			var handles = pointer.editing._handles,
				handle = handles[2];

			handle.fire('click', { target: handle });

			for (var i = 0, l = handles.length; i < l - 1; i++) {
				expect(handles[i]._id).to.equal(i);
			}
		});
	});

	describe("#_onVertexUpdate", function() {
		it("Should only update the vertex being dragged.", function() {
			var initialCoords = pointer.getPoints(),
				initialLength = initialCoords.length,
				handle2 = pointer.editing._handles[4],
				newCoords = new L.Point(0, 30),
				coordinates, arg;

			handle2.setLatLng(handle2._textboxCoordsToLatLng(newCoords));
			handle2.fire('drag', { target: handle2 });

			expect(pointer.getPoints().length).to.equal(initialLength);

			expect(_onVertexUpdate.called).to.equal(true);

			for (var i = 0, length = _onVertexUpdate.args.length; i < length; i++) {
				arg = _onVertexUpdate.args[i][0];

				expect(arg.handle._id).to.equal(handle2._id);
				expect(arg.handle._handleOffset).to.equal(handle2._handleOffset);
				expect(arg.handle._type).to.equal(handle2._type);
			}

			coordinates = pointer.getPoints();

			/* These handles were not modified at all. */
			expect(coordinates[0]).to.be.closeToPoint(initialCoords[0]);
			expect(coordinates[1]).to.be.closeToPoint(initialCoords[1]);
			expect(coordinates[3]).to.be.closeToPoint(initialCoords[3]);
		});

		it("Should set the correct vertex to the correct coordinates", function() {
			var initialLength = pointer.getPoints().length,
				handle = pointer.editing._handles[2],
				newCoords = new L.Point(10, 0);

			expect(handle._type).to.equal('vertex');
			handle.setLatLng(handle._textboxCoordsToLatLng(newCoords));

			handle.fire('drag', { target: handle });

			expect(pointer.getPoints()[1]).to.be.closeToPoint(newCoords);
			expect(pointer.getPoints().length).to.equal(initialLength);
		});
	});
});


text:
<!DOCTYPE html
  PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   <title>discreteDensityModelsShootout</title><meta name="generator" content="MATLAB 7.12"><link rel="schema.DC" href="http://purl.org/dc/elements/1.1/"><meta name="DC.date" content="2012-03-27"><meta name="DC.source" content="discreteDensityModelsShootout.m">

Contents

Data

Models/ methods

CV

Plot performance

Visualize models themselves

%PMTKslow

% Compare various joint density models on categorical (mostly binary) datsets
% We visualize the learned structuers and evaluate loglik and
% imputation error on test sets

Data

labels is N*D, where labels(n,d) in {1..Nstates(d)}

Nfolds = 1;
% pcTrain and pcTest do not need to sum to one
% This way, you can use a fraction of the overall data
pcTrain = 0.1; pcTest = 0.1;
pcMissing =  0.3;

%dataName = 'SUN09';
dataName = 'newsgroups';
%dataName = 'newsgroups1';
%dataName = 'ases4';

switch dataName
  case 'newsgroups'
  loadData('20news_w100');
  % documents, wordlist, newsgroups, groupnames
  labels = double(full(documents))'+1; % 16,642 documents by 100 words  (sparse logical  matrix)
  nodeNames = wordlist;
  Nstates = 2*ones(1,numel(nodeNames));

  case 'newsgroups1'
    load(['a3newsgroups.mat']);
    % select class
    classId = 1;%there are 4 classes
    idx = find(newsgroups == classId);
    data.discrete = documents(:,idx)' + 1;
    data.discrete = data.discrete'; %KPM
    data.continuous = [];
    % it is possible that some words are always absent
    % In this case, nClass(d)=1 but we want it to be 2
    %nClass = max(data.discrete,[],2);
    nClass = 2*ones(1, size(data.discrete,1));
    labels = data.discrete'; % N*D
    Nstates = nClass;
    nodeNames = wordlist;

  case 'SUN09'
  loadData('sceneContextSUN09', 'ismatfile', false)
  load('SUN09data')
  % 8684 images x 111 tags
  % we merge the training and test data into one big blob
  % so that we can use CV
  labels = [data.train.presence; data.test.presence]+1;
  nodeNames = data.names;
  clear data
  Nstates = 2*ones(1,numel(nodeNames));

 case 'voting'
   load('house-votes-84')
   Y = data.X; % 435 x 17
   % omit columns 3,11,12, which are not very correlated
   %ndx = [1:2 4:10 13:17];
   ndx = 1:17;
   Y = Y(:,ndx);
   % omit rows with any Nan - this leaves 232 rows
   idx = find(~sum(isnan(Y),2));
   labels = Y(idx, :);
   nodeNames = data.names(ndx);
   Nstates = 2*ones(1,numel(nodeNames));

  case 'temperature'
    load deshpande_intel % X is 18,054 x 54, 0,1,2,3
    %labels = (X>=2)+1; % binarize
    labels = X+1;
    D = size(labels,2);
    nodeNames = cellfun(@(d) sprintf('n%d', d), num2cell(1:D), 'uniformoutput', false);
    Nstates = nunique(labels(:))*ones(1,numel(nodeNames));

  case 'ases4'
    %a = importdata([dirName 'asesLarge.txt']);
    %Y = a.data;
    %names = a.colheaders;
    load('ases'); % Y is 18253x52 double, names is 1x53 cell
    %  remove rows with any missing values
    idx = find(~sum(isnan(Y),2));
    X = Y(idx,:); % 8735 * 53
    labels = X(:,[3:44]);
    names = names(3:44);
    nClass = max(labels,[],1);
    % currently KPM's code assumes all nodes have the same #values
    % So we extract features with 4 states each
    ndx = find(nClass==4);
    labels = labels(:, ndx); % 8735 * 17
    names = names(ndx);
    nClass = 4*ones(1,numel(names));
    Nstates = nClass;
    nodeNames = names;

    case 'ases'
    %a = importdata([dirName 'asesLarge.txt']);
    %Y = a.data;
    %names = a.colheaders;
    load('ases'); % Y is 18253x52 double, names is 1x53 cell
    %  remove rows with any missing values
    idx = find(~sum(isnan(Y),2));
    X = Y(idx,:); % 8735 * 53
    labels = X(:,[3:44]);
    names = names(3:44);
    nClass = max(labels,[],1);
    Nstates = nClass;
    nodeNames = names;

end
isbinary =  all(Nstates==2);
nClass = Nstates;

%{
figure; imagesc(labels); colorbar
title(sprintf('%s, N=%d, D=%d', dataName, size(labels,1), size(labels,2)))
drawnow
%}

% Where to store plots (set figFolder = [] to turn of printing)
if isunix
  figFolder = '/home/kpmurphy/Dropbox/figures/googleJointModelsTalk';
end
if ismac
  figFolder = '/Users/kpmurphy/Dropbox/figures/googleJointModelsTalk';
end
figFolder = []; % for public use, turn off figure saving

Models/ methods

methods = [];
m = 0;

m = m + 1;
methods(m).modelname = 'indep';
methods(m).fitFn = @(labels) discreteFit(labels);
methods(m).logprobFn = @(model, labels) discreteLogprob(model, labels);
methods(m).predictMissingFn = @(model, labels) discretePredictMissing(model, labels);

%%%%%%%%%%%%%% Tree

%{
m = m + 1;
methods(m).modelname = 'tree';
methods(m).fitFn = @(labels) treegmFit(labels);
methods(m).logprobFn = @(model, labels) treegmLogprob(model, labels);
methods(m).predictMissingFn = @(model, labels) treegmPredictMissing(model, labels);
%}

%%%%%%%%%%%%%% DGM
%{
% For debugging - an empty dag should be the same as the independent model
m = m + 1;
methods(m).modelname = 'dgm-empty';
methods(m).fitFn = @(labels) dgmFitStruct(labels, 'nodeNames', nodeNames, 'emptyGraph', true);
methods(m).logprobFn = @(model, labels) dgmLogprob(model, 'obs', labels);
%}

%{
% For debugging - if we initialize search at a tree and perform 0
% iterations of DAG search, we should get the same resutls as treegmFit
m = m + 1;
methods(m).modelname = 'dgm-tree';
methods(m).fitFn = @(labels) dgmFitStruct(labels, 'nodeNames', nodeNames, 'maxFamEvals', 500, ...
  'figFolder', figFolder, 'nrestarts', 0, 'maxIter', 0, 'initMethod', 'tree');
methods(m).logprobFn = @(model, labels) dgmLogprob(model, 'obs', labels);
%}

%{
% Using no edge restrictions is very slow!
m = m + 1;
methods(m).modelname = 'dgm-init-tree-restrict-none';
methods(m).fitFn = @(labels) dgmFitStruct(labels, 'nodeNames', nodeNames, 'maxFamEvals', 500, ...
  'figFolder', figFolder, 'nrestarts', 2, 'initMethod', 'tree', 'edgeRestrict', 'none');
methods(m).logprobFn = @(model, labels) dgmLogprob(model, 'obs', labels);
%}

%{
m = m + 1;
methods(m).modelname = 'dgm-init-tree';
methods(m).fitFn = @(labels) dgmFitStruct(labels, 'nodeNames', nodeNames, 'maxFamEvals', 1000, ...
  'figFolder', figFolder, 'nrestarts', 0, 'initMethod', 'tree', 'edgeRestrict', 'MI');
methods(m).logprobFn = @(model, labels) dgmLogprob(model, 'obs', labels);
%}

%{
m = m + 1;
methods(m).modelname = 'dgm-init-empty';
methods(m).fitFn = @(labels) dgmFitStruct(labels, 'nodeNames', nodeNames, 'maxFamEvals', 1000, ...
  'figFolder', figFolder, 'nrestarts', 2, 'initMethod', 'empty', 'edgeRestrict', 'MI');
methods(m).logprobFn = @(model, labels) dgmLogprob(model, 'obs', labels);

%}

%{

m = m + 1;
methods(m).modelname = 'dgm-init-tree-restrict-L1';
methods(m).fitFn = @(labels) dgmFitStruct(labels, 'nodeNames', nodeNames, 'maxFamEvals', 1000, ...
  'figFolder', figFolder, 'nrestarts', 2, 'initMethod', 'tree', 'edgeRestrict', 'L1');
methods(m).logprobFn = @(model, labels) dgmLogprob(model, 'obs', labels);

%}

%%%%%%%%%%%%%% MRF

%{
m = m + 1;
lambdaNode = 0.1; lambdaEdge = 50;
methods(m).modelname = 'mrf-L1';
methods(m).fitFn = @(labels) mrf2FitStruct(labels, ...
  'lambdaNode', lambdaNode, 'lambdaEdge', lambdaEdge, 'nstates', 2*ones(1,numel(nodeNames)), ...
  'nodeNames', nodeNames);
methods(m).logprobFn = @(model, labels) mrf2Logprob(model, labels);
%[logZBF, nodeBelBF] = crf2InferNodes(model, X(testNdx,:,:), [], 'infMethod', 'bruteforce');
%}

%%%%%%%%%%%%%% Mix

%{
Ks = [1,5,20,40];
for kk=1:numel(Ks)
  K = Ks(kk);
  m = m + 1;
  alpha = 1.1;
  %methods(m).modelname = sprintf('mixK%d,a%2.1f', K, alpha);
  methods(m).modelname = sprintf('mix%d', K);
  methods(m).fitFn = @(labels) mixDiscreteFit(labels, K, 'maxIter', 30, ...
    'verbose', false, 'alpha', 1.1);
  methods(m).logprobFn = @(model, labels) mixDiscreteLogprob(model, labels);
  methods(m).predictMissingFn = @(model, labels) mixDiscretePredictMissing(model, labels);
end
%}

%%%%%%%%%%%%%% Categorical FA

%{
Ks = [1,5,20,40];
for kk=1:numel(Ks)
  K = Ks(kk);
  m = m + 1;
  methods(m).modelname = sprintf('dFA-%d', K);
  methods(m).fitFn = @(labels) catFAfit(labels, [],  K,  'nClass', Nstates, ...
    'maxIter', 15, 'verbose', true);
  methods(m).logprobFn = @(model, labels) nan(size(labels,1),1);
  methods(m).predictMissingFn = @(model, labels) catFApredictMissing(model, labels, []);
end
%}

%%%%%%%%%%%%%% binary FA

%Ks = [150,200,250,300];
Ks = [1,20,50,100,150];
for kk=1:numel(Ks)
  K = Ks(kk);
  m = m + 1;
  methods(m).modelname = sprintf('bFA-%d', K);
  methods(m).fitFn = @(labels) binaryFAfit(labels,  K,   ...
    'maxIter', 15, 'verbose', true, 'computeLoglik', false);
  methods(m).logprobFn = @(model, labels) nan(size(labels,1),1);
  methods(m).predictMissingFn = @(model, labels) argout(2, @binaryFApredictMissing, model, labels);
end

Nmethods = numel(methods);

CV

setSeed(0);
N = size(labels, 1)
if Nfolds == 1
  % it is important to shuffle the rows to eliminate ordering effects
  % (the newsgroup data is sorted by category)
  perm = randperm(N);
  stop = floor(N*pcTrain);
  trainfolds{1}  = perm(1:stop);
  stop2 = floor(N*pcTest);
  testfolds{1} = perm(stop+1: stop+stop2);
  %fprintf('train=1:%d, test = %d:%d\n', stop, stop+1, stop+stop2);
  %trainfolds{1} = 1:N;
  %testfolds{1} = 1:N;
else
  randomize = true;
  [trainfolds, testfolds] = Kfold(N, Nfolds, randomize);
end

loglik_models = zeros(Nfolds, Nmethods);
imputation_err_entropy = zeros(Nfolds, Nmethods);
imputation_err_binary = zeros(Nfolds, Nmethods);

for fold=1:Nfolds

  train.labels = labels(trainfolds{fold}, :);
  test.labels = labels(testfolds{fold}, :);
  [Ntrain, Nnodes] = size(train.labels);
  [Ntest, Nnodes2] = size(test.labels);

  fprintf('fold %d of %d, Ntrain %d, Ntest %d\n', ...
    fold, Nfolds, Ntrain, Ntest);

  missingMask = rand(Ntest, Nnodes) < pcMissing;
  test.labelsMasked = test.labels;
  test.labelsMasked(missingMask) = nan;

  models = cell(1, Nmethods);
  methodNames = cell(1, Nmethods);
  for m=1:Nmethods
    methodNames{m} = sprintf('%s', methods(m).modelname);
    fprintf('fitting %s\n', methodNames{m});
    models{m} = methods(m).fitFn(train.labels);
  end

  ll = zeros(1, Nmethods);
  imputationErr = zeros(1,Nmethods);
  imputationErrBinary = zeros(1,Nmethods);
  for m=1:Nmethods
    fprintf('evaluating %s\n', methodNames{m});
    ll(m) = sum(methods(m).logprobFn(models{m}, test.labels))/Ntest;

    if isfield(methods(m), 'predictMissingFn')
      pred = methods(m).predictMissingFn(models{m}, test.labelsMasked);
      % for binary data - MSE is fine
      probOn = pred(:,:,2);
      testBinary = (test.labels==2);
      imputationErrBinary(m) = sum(sum((probOn-testBinary).^2))/Ntest;

      %{
      % for K-ary data - MSE not so meaningful
      % so we use cross entropy
      [~,truth3d] = dummyEncoding(test.labels, Nstates);
      %imputationErr(m) = sum(sum(sum((truth3d-pred).^2)))/Ntest;
      %logprob = sum(sum(log(sum(truth3d .* pred, 3))))/Ntest;
      logprob = reshape(log2(pred(find(truth3d)) + eps), [Ntest Nnodes]);
      logprobAvg = mean(logprob(:));
      logprobAvg2 = mean(logprob(missingMask(:)));

      % Just assess performance on the missing entries
      % This does not affect the relative performance of methods
      %logprob = log(sum(truth3d .* pred, 3)); % N*D
      %logprobAvg = sum(sum(logprob(missingMask)))/sum(missingMask(:));

      %logprob = sum(truth3d(missingMask3d) .* log2(pred(missingMask3d)+eps), 3); % logprob(n,d)
      %logprobAvg = sum(sum(logprob))/(Ntest*length(nClass))
      %}

      % Emt's evaluation code
      nClass = Nstates;
      yd = test.labelsMasked';
      ydT = test.labels';
      ydT_oneOfM = encodeDataOneOfM(ydT, nClass, 'M');
      yd_oneOfM = encodeDataOneOfM(yd, nClass, 'M');
      N = size(yd_oneOfM,2);
      miss = isnan(yd_oneOfM);
      % pred is N * D * K
      pred2 = permute(pred, [3 2 1]); % K D N
      pred3 = reshape(pred2, [sum(nClass) Ntest]); % KD * N
      %yhatD = reshape(pred+eps, [Ntest sum(nClass)])';

      % if predict [0 0], replace with eps
      M = nClass;
      for d = 1:length(M)
        idx = sum(M(1:d-1))+1:sum(M(1:d));
        p1 = pred3(idx,:);
        if ~isempty(find(sum(p1,2) == 0))
          p1 = p1 + eps;
          p1 = bsxfun(@times, p1, 1./sum(p1));
        end
        pred3(idx,:) = p1;
      end
      yhatD = pred3;
      entrpyD = -sum(ydT_oneOfM(miss).*log2(yhatD(miss)))/(Ntest*length(nClass));
      %entrpyD = -sum(ydT_oneOfM(miss).*log2(yhatD(miss)))/(sum(miss(:)));

      imputationErr(m) =  entrpyD;
    end
  end
  loglik_models(fold, :) = ll;
  imputation_err_entropy(fold, :) = imputationErr;
  imputation_err_binary(fold, :) = imputationErrBinary;
end % fold

%{
% Debug - check that tree has correct marginals
% Compute unconditional marginals from tree
mTree = strfindCell('tree', methodNames);
[logZ, nodeBelTree] = treegmInferNodes(models{mTree});

% Compare to marginals from indep model
mIndep = strfindCell('indep', methodNames);
nodeBelIndep = models{mIndep}.T;
assert(approxeq(nodeBelIndep, nodeBelTree))
%}

%{
% Debug - check that independent model is same
% as mixture with 1 component
mMix = strfindCell('mix1', methodNames);
mIndep = strfindCell('indep', methodNames);
predIndep = methods(mIndep).predictMissingFn(models{mIndep}, test.labelsMasked);
predMix = methods(mMix).predictMissingFn(models{mMix}, test.labelsMasked);
assert(approxeq(predIndep, predMix))
%predTree = methods(mTree).predictMissingFn(models{mTree}, test.labelsMasked);
%}

N =
       16242
fold 1 of 1, Ntrain 1624, Ntest 1624
fitting indep
fitting bFA-1
initializing model for EM
1	 loglik: 0
2	 loglik: 0
3	 loglik: 0
4	 loglik: 0
5	 loglik: 0
6	 loglik: 0
7	 loglik: 0
8	 loglik: 0
9	 loglik: 0
10	 loglik: 0
11	 loglik: 0
12	 loglik: 0
13	 loglik: 0
14	 loglik: 0
15	 loglik: 0
16	 loglik: 0
fitting bFA-20
initializing model for EM
1	 loglik: 0
2	 loglik: 0
3	 loglik: 0
4	 loglik: 0
5	 loglik: 0
6	 loglik: 0
7	 loglik: 0
8	 loglik: 0
9	 loglik: 0
10	 loglik: 0
11	 loglik: 0
12	 loglik: 0
13	 loglik: 0
14	 loglik: 0
15	 loglik: 0
16	 loglik: 0
fitting bFA-50
initializing model for EM
1	 loglik: 0
2	 loglik: 0
3	 loglik: 0
4	 loglik: 0
5	 loglik: 0
6	 loglik: 0
7	 loglik: 0
8	 loglik: 0
9	 loglik: 0
10	 loglik: 0
11	 loglik: 0
12	 loglik: 0
13	 loglik: 0
14	 loglik: 0
15	 loglik: 0
16	 loglik: 0
fitting bFA-100
initializing model for EM
1	 loglik: 0
2	 loglik: 0
3	 loglik: 0
4	 loglik: 0
5	 loglik: 0
6	 loglik: 0
7	 loglik: 0
8	 loglik: 0
9	 loglik: 0
10	 loglik: 0
11	 loglik: 0
12	 loglik: 0
13	 loglik: 0
14	 loglik: 0
15	 loglik: 0
16	 loglik: 0
fitting bFA-150
initializing model for EM
1	 loglik: 0
2	 loglik: 0
3	 loglik: 0
4	 loglik: 0
5	 loglik: 0
6	 loglik: 0
7	 loglik: 0
8	 loglik: 0
9	 loglik: 0
10	 loglik: 0
11	 loglik: 0
12	 loglik: 0
13	 loglik: 0
14	 loglik: 0
15	 loglik: 0
16	 loglik: 0
evaluating indep
evaluating bFA-1
evaluating bFA-20
evaluating bFA-50
evaluating bFA-100
evaluating bFA-150

Plot performance

[styles, colors, symbols, plotstr] =  plotColors();

% NLL - for catFA, which cannot compute valid loglik,
% we use NaNs
figure;
ndx = 1:Nmethods;
if Nfolds==1
  plot(-loglik_models(ndx), 'x', 'markersize', 12, 'linewidth', 2)
  axis_pct
  -loglik_models
else
  boxplot(-loglik_models(:, ndx))
end
set(gca, 'xtick', 1:numel(ndx))
set(gca, 'xticklabel', methodNames(ndx))
%xticklabelRot(methodNames(ndx), -45);
title(sprintf('NLL on %s, D=%d, Ntr=%d, Nte=%d', ...
  dataName, Nnodes, Ntrain, Ntest))
printPmtkFigure(sprintf('negloglik-%s.png', dataName), 'png', figFolder);

% imputation error
figure;
ndx = 1:Nmethods;
if Nfolds==1
  plot(imputation_err_entropy(ndx), 'x', 'markersize', 12, 'linewidth', 2)
  axis_pct
 imputation_err_entropy
else
  boxplot(imputation_err_entropy(:, ndx))
end
set(gca, 'xtick', 1:numel(ndx))
set(gca, 'xticklabel', methodNames(ndx))
%xticklabelRot(methodNames(ndx), -45);
title(sprintf('imputation error (cross entropy) on %s, %5.3fpc missing, D=%d, Ntr=%d, Nte=%d', ...
  dataName, pcMissing, Nnodes, Ntrain, Ntest))
printPmtkFigure(sprintf('imputation-%s.png', dataName), 'png', figFolder);

% mse error
figure;
ndx = 1:Nmethods;
if Nfolds==1
  plot(imputation_err_binary(ndx), 'x', 'markersize', 12, 'linewidth', 2)
  axis_pct
else
  boxplot(imputation_err_binary(:, ndx))
end
set(gca, 'xtick', 1:numel(ndx))
set(gca, 'xticklabel', methodNames(ndx))
%xticklabelRot(methodNames(ndx), -45);
title(sprintf('imputation error (mse) on %s, %5.3fpc missing, D=%d, Ntr=%d, Nte=%d', ...
  dataName, pcMissing, Nnodes, Ntrain, Ntest))
printPmtkFigure(sprintf('imputation-mse-%s.png', dataName), 'png', figFolder);

ans =
  Columns 1 through 2
  15.580054998137765                 NaN
  Columns 3 through 4
                 NaN                 NaN
  Columns 5 through 6
                 NaN                 NaN
imputation_err_entropy =
  Columns 1 through 2
   0.068498305595224   0.068440811536275
  Columns 3 through 4
   0.067584901143097   0.067002260694711
  Columns 5 through 6
   0.066466492812077   0.066352039080297

Visualize models themselves

%{

m = strfindCell('tree', methodNames);
if ~isempty(m)
  tree = models{m};
  % The tree is undirected, but for some reason, gviz makes directed graphs
  % more readable than undirected graphs
  fname = fullfile(figFolder, sprintf('tree-%s', dataName))
  graphviz(tree.edge_weights, 'labels', nodeNames, 'directed', 1, 'filename', fname);
end
%}

%{
m = strfindCell('dgm', methodNames);
if ~isempty(m)
  dgm = models{m};
  % The node names get permuted so we must use dgm.nodeNames
  fname = fullfile(figFolder, sprintf('dgm-%s', dataName))
  graphviz(dgm.G, 'labels', dgm.nodeNames, 'directed', 1, 'filename', fname);
end
%}

%{
m = strfindCell('mrf-L1', methodNames);
if ~isempty(m)
  mrf = models{m};
  fname = fullfile(figFolder, sprintf('mrf-L1-%s', dataName))
  graphviz(mrf.G, 'labels', nodeNames, 'directed', 0, 'filename', fname);
end

m = strfindCell('mix10', methodNames);
if ~isempty(m)
  mix = models{m};
  K = mix.nmix;
  [nr,nc] = nsubplots(K);
  %figure;
  for k=1:K
    T = squeeze(mix.cpd.T(k,2,:));
    ndx = topAboveThresh(T, 5, 0.1);
    memberNames = sprintf('%s,', nodeNames{ndx});
    disp(memberNames)
    %subplot(nr, nc, k)
    %bar(T);
    %title(sprintf('%5.3f', mix.mixWeight(k)))
  end
end
%}

%{
% Fit a depnet to the labels
%model = depnetFit(labels, 'nodeNames', nodeNames, 'method', 'ARD');
model = depnetFit(labels, 'nodeNames', nodeNames, 'method', 'MI');
fname = fullfile(figFolder, sprintf('depnet-MI-%s', dataName))
graphviz(model.G, 'labels', nodeNames, 'directed', 1, 'filename', fname);
%}

      Published with MATLAB® 7.12


text:
        body {
            background-color: #FFFFFF;
        }
        /*FORMULARIO*/
        form {
            display: inline-block;
            font-family: 'Roboto', Arial, Helvetica, sans-serif;
            font-size:12px;

            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            -ms-box-sizing: border-box;
            -o-box-sizing: border-box;
            box-sizing: border-box;
            width: 100%;
        }
        form label {
            font-weight:500;
            text-align:left;
        }
        form input[type="text"],
        form input[type="password"],
        form input[type="email"] {
            background-color:#FFFFFF;
            border-radius: 3px;
            box-shadow: inset 1px 1px 3px #DDDDDD;
            border: 1px #CCCCCC solid;
            display: block;
            font-family: 'Roboto', Arial, Helvetica, sans-serif;
            font-size: 14px;
            height: 39px;
            line-height: 37px;
            padding: 0 10px;
            margin:5px 0;
            outline: none;

            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            -ms-box-sizing: border-box;
            -o-box-sizing: border-box;
            box-sizing: border-box;
            width:100%;
        }
        form input[type=submit],
        form input[type=reset],
        form input[type=button] {
            background-color:#F3F3F3;
            border:1px #D8D8D8 solid;
            color:#424242;
            cursor:pointer;
            display:inline-block;
            font:500 13px 'Roboto', Arial, Helvetica, sans-serif;
            height: 35px;
            line-height: 33px;
            margin-left:0;
            min-width:72px;
            padding:0 10px;
            text-decoration:none;
            width:100%;

            border-radius:3px;
            -webkit-border-radius:3px;
            -moz-border-radius:3px;

            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            -ms-box-sizing: border-box;
            -o-box-sizing: border-box;
            box-sizing: border-box;
            width:100%;

            filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#F5F5F5', endColorstr='#F1F1F1');
            background: -webkit-gradient(linear, left bottom, left top, from(#F1F1F1), to(#F5F5F5));
            background: -moz-linear-gradient(bottom,  #F1F1F1,  #F5F5F5);
        }
        form input[type=submit]:focus,
        form input[type=reset]:focus,
        form input[type=button]:focus {
            -moz-box-shadow: inset 0 0 0 1px #fff;
            -webkit-box-shadow: inset 0 0 0 1px #fff;
            box-shadow: inset 0 0 0 1px #fff;
        }
        form input[type=submit]:hover,
        form input[type=reset]:hover,
        form input[type=button]:hover {
            border-color:#C6C6C6;
            background-color:#F7F7F7;
            -moz-box-shadow:0 2px 1px #ECECEC;
            -webkit-box-shadow:0 2px 1px #ECECEC;
            box-shadow:0 2px 1px #ECECEC;

            filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#F8F8F8', endColorstr='#F1F1F1');
            background: -webkit-gradient(linear, left bottom, left top, from(#F1F1F1), to(#F8F8F8));
            background: -moz-linear-gradient(bottom,  #F1F1F1,  #F8F8F8);
        }

        /*Blue Button*/
        form input[type=submit].blue,
        form input[type=reset].blue,
        form input[type=button].blue,
        button.blue,
        a.button.blue {
            background-color:#4787ed;
            background: -moz-linear-gradient(top, #4d90fe, #4787ed);
            background: -ms-linear-gradient(top, #4d90fe, #4787ed);
            background: -o-linear-gradient(top, #4d90fe, #4787ed);
            background: -webkit-linear-gradient(top, #4d90fe, #4787ed);
            background: linear-gradient(top, #4d90fe, #4787ed);
            border: 1px solid #3079ed;
            color: #fff;
        }
        form input[type=submit].blue:hover,
        form input[type=reset].blue:hover,
        form input[type=button].blue:hover,
        button.blue:hover,
        a.button.blue:hover {
            background: -moz-linear-gradient(top, #4d90fe, #357ae8);
            background: -ms-linear-gradient(top, #4d90fe, #357ae8);
            background: -o-linear-gradient(top, #4d90fe, #357ae8);
            background: -webkit-linear-gradient(top, #4d90fe, #357ae8);
            background: linear-gradient(top, #4d90fe, #357ae8);
            border: 1px solid #2f5bb7;
            color: #fff;
        }
        /*Blue Button End*/

        /*FINAL FORMULARIO*/
        #wrapper {
            left: 50%;
            margin-left: -175px;
            margin-top: 100px;
            position: absolute;
            width: 350px;
        }
        #wrapper h1 {
            color: #555;
            font-family: 'Open Sans Light';
            font-size: 35px;
            margin: 18px 0;
            line-height: 1.2em;
            text-align: center;
        }
        #wrapper h1 em {
            color: #AAA;
            display: block;
            font-family: 'Open Sans Semibold';
            font-size: 13px;
            font-style: normal;
            letter-spacing: 1px;
            line-height: 1em;
            text-transform: uppercase;
        }
        #wrapper span {
            display: block;
            font-size: 18px;
            font-weight: 400;
            line-height: 1em;
            margin-top: 20px;
        }
        #wrapper .content {
            padding: 10px 20px;
        }

/*
*   Navegadores recomendados
*/
.web_browser_recommended {
    bottom: 20px;
    color: #666;
    cursor: default;
    font-family: 'Roboto', Arial, Helvetica, sans-serif;
    font-size: 13px;
    position: absolute;
    text-align: center;
    width: 100%;
}

/*
*   Leyenda de tipo de usuario
*/
p.user_type {
    font-family: 'Roboto', Arial, Helvetica;
    font-size: 13px;
    font-weight: 500;
    margin-right: 20px;
    position: relative;
    text-align: right;
    text-transform: none;
}
p.user_type a {
    color: #444444;
    text-decoration: none;
}

/*
*   Notificaciones
*/
p.notify {
    background-color:#F9EDBE;
    border:1px #F0C36D solid;
    border-radius:4px;
    -moz-border-radius:4px;
    -webkit-border-radius:4px;
    display: inline;
    font-family: Arial, Helvetica;
    font-weight:bold;
    font-size:11px;
    padding:6px 8px;
    position:absolute;
    top:30px;
    left: 50%;
    transform: translateX(-50%);

    -moz-box-shadow:0 0 3px #CCC;
    -webkit-box-shadow:0 0 3px #CCC;
    box-shadow:0 0 3px #CCC;
    width: auto;
    z-index:999;
}


text:
'use strict'

// const defaultConfig = require('./default-config.json')
const ipfsd = require('ipfsd-ctl')
const series = require('async/series')
const eachSeries = require('async/eachSeries')
const once = require('once')

module.exports = Factory

function Factory () {
  if (!(this instanceof Factory)) {
    return new Factory()
  }

  let nodes = []

  this.spawnNode = (repoPath, config, callback) => {
    if (typeof repoPath === 'function') {
      callback = repoPath
      repoPath = undefined
    }
    if (typeof config === 'function') {
      callback = config
      config = undefined
    }

    // if (!repoPath) {
    //   repoPath = '/tmp/.ipfs-' + Math.random()
    //                             .toString()
    //                             .substring(2, 8)
    // }

    // TODO
    //   - [ ] Support custom repoPath
    //   - [ ] Support custom config
    // This will come once the new ipfsd-ctl is
    // complete: https://github.com/ipfs/js-ipfsd-ctl/pull/89

    spawnEphemeralNode((err, node) => {
      if (err) {
        return callback(err)
      }
      nodes.push(node)
      callback(null, node.apiAddr)
    })
  }

  this.dismantle = (callback) => {
    eachSeries(nodes, (node, cb) => {
      cb = once(cb)
      node.stopDaemon(cb)
    }, (err) => {
      if (err) {
        return callback(err)
      }
      nodes = []

      callback()
    })
  }
}

function spawnEphemeralNode (callback) {
  ipfsd.disposable((err, node) => {
    if (err) {
      return callback(err)
    }
    // Note: we have to set each config value
    // independently since the config/replace endpoint
    // doesn't work as expected
    series([
      (cb) => {
        const configValues = {
          Bootstrap: [],
          Discovery: {},
          'HTTPHeaders.Access-Control-Allow-Origin': ['*'],
          'HTTPHeaders.Access-Control-Allow-Credentials': 'true',
          'HTTPHeaders.Access-Control-Allow-Methods': ['PUT', 'POST', 'GET']
        }

        eachSeries(Object.keys(configValues), (configKey, cb) => {
          node.setConfig(`API.${configKey}`, JSON.stringify(configValues[configKey]), cb)
        }, cb)
      },
      (cb) => node.startDaemon(cb)
    ], (err) => {
      if (err) {
        return callback(err)
      }

      callback(null, node)
    })
  })
}