class Tailwindcss::Purger

def escape_class_selector(class_name)

def escape_class_selector(class_name)
  class_name.gsub(/\A\d|[^-_a-z0-9]/, '\\\\\0')
end

def extract_class_names(string)

def extract_class_names(string)
  string.scan(CLASS_NAME_PATTERN).uniq.sort!
end

def extract_class_names_from(files)

def extract_class_names_from(files)
  Array(files).flat_map { |file| extract_class_names(file.read) }.uniq.sort!
end

def initialize(keep_these_class_names)

def initialize(keep_these_class_names)
  @keep_these_class_names = keep_these_class_names
end

def keep_these_selectors_pattern

def keep_these_selectors_pattern
  @keep_these_selectors_pattern ||= begin
    escaped_classes = @keep_these_class_names.map { |name| Regexp.escape self.class.escape_class_selector(name) }
    /(?:\A|,)[^.,{]*(?:[.](?:#{escaped_classes.join("|")})#{CLASS_BREAK}[^.,{]*)*(?=[,{])/
  end
end

def purge(input, keeping_class_names_from_files:)

def purge(input, keeping_class_names_from_files:)
  new(extract_class_names_from(keeping_class_names_from_files)).purge(input)
end

def purge(input)

def purge(input)
  conveyor = Conveyor.new(input)
  until conveyor.done?
    conveyor.discard(COMMENTS_AND_BLANK_LINES) \
    or conveyor.conditionally_keep(PROPERTIES) { conveyor.staged_output.last != "" } \
    or conveyor.conditionally_keep(END_OF_BLOCK) { not conveyor.staged_output.pop } \
    or conveyor.stage_output(CLASSLESS_BEGINNING_OF_BLOCK) \
    or conveyor.stage_output(BEGINNING_OF_BLOCK) { |match| purge_beginning_of_block(match.to_s) } \
    or raise "infinite loop"
  end
  conveyor.output
end

def purge_beginning_of_block(string)

def purge_beginning_of_block(string)
  purged = string.scan(keep_these_selectors_pattern).join
  unless purged.empty?
    purged.sub!(/\A,\s*/, "")
    purged.rstrip!
    purged << " {\n"
  end
  purged
end