├── .gitignore ├── .gitmodules ├── .rspec ├── CHANGELOG ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.rdoc ├── Rakefile ├── autotest └── discover.rb ├── fech.gemspec ├── lib ├── fech.rb └── fech │ ├── comparison.rb │ ├── csv.rb │ ├── default_translations.rb │ ├── fech_utils.rb │ ├── filing.rb │ ├── map_generator.rb │ ├── mapped.rb │ ├── mappings.rb │ ├── rendered_maps.rb │ ├── senate_filing.rb │ ├── translator.rb │ └── version.rb ├── spec ├── comparison_spec.rb ├── csv_spec.rb ├── data │ ├── 1247604.fec │ ├── 425925.fec │ ├── 467627.fec │ ├── 723604.fec │ ├── 730635.fec │ ├── 747058.fec │ ├── 748730.fec │ ├── 752356.fec │ ├── 753533.fec │ ├── 764901.fec │ ├── 765310.fec │ ├── 767339.fec │ ├── 771694.fec │ ├── 82094.fec │ ├── 862554.fec │ └── 97405.fec ├── default_translations_spec.rb ├── fech_utils_spec.rb ├── filing_spec.rb ├── map_generator_spec.rb ├── mapped_spec.rb ├── mappings_spec.rb ├── sources │ ├── F24.csv │ ├── F3P.csv │ ├── F3P31.csv │ ├── SchA.csv │ ├── SchB.csv │ ├── SchC.csv │ ├── headers │ │ ├── 3.csv │ │ ├── 5.0.csv │ │ ├── 5.1.csv │ │ ├── 5.2.csv │ │ ├── 5.3.csv │ │ ├── 6.1.csv │ │ ├── 6.2.csv │ │ ├── 6.3.csv │ │ ├── 6.4.csv │ │ ├── 7.0.csv │ │ ├── 8.0.csv │ │ └── ignore.csv │ └── sa.csv ├── spec_helper.rb └── translator_spec.rb └── tasks └── fech.rake /.gitignore: -------------------------------------------------------------------------------- 1 | sources/rows/* 2 | pkg/* 3 | .bundle 4 | *.gem 5 | .yardoc/* 6 | doc/* 7 | 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "sources"] 2 | path = sources 3 | url = git@github.com:dwillis/fech-sources.git 4 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --colour 2 | --profile 3 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | 1.7 / 2015-03-28 2 | 3 | * Additions 4 | 5 | * Support for F3Z and SA3L transactions in F3 filings. 6 | * Better support for Ruby 2.1.2 7 | 8 | * Bug fixes 9 | 10 | * Fixed three canonical slugs in sources/F3.csv 11 | 12 | 1.6.4 / 2014-03-11 13 | 14 | * Bug fixes 15 | 16 | * Fixed office state and district mappings in Schedule E transactions. 17 | 18 | 1.6.3 / 2014-01-22 19 | 20 | * Bug fixes 21 | 22 | * Ensure that a Translator object is available to all Filing objects, even if one wasn't created when the Filing was instantiated. (thx, @abstrctn!) 23 | 24 | 1.6.2 / 2014-01-15 25 | 26 | * Bug fixes 27 | 28 | * Added dissemination date to SE transactions. 29 | 30 | 1.6.1 / 2014-01-15 31 | 32 | * Bug fixes 33 | 34 | * Added version 8.1 mappings for F24 and F13 filings. 35 | 36 | 1.6.0 / 2014-01-14 37 | 38 | * Breaking changes 39 | 40 | * F5 Form - deleted 16th field, switched 16th & 17th fields and added 20th field. 41 | * F57 Form - changed :expenditure_date to :dissemination_date for field 18. 42 | * Schedule E records - added a new 20th field, old 20th field moved to 22nd, 35th & 36th fields are switched. 43 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | # Specify your gem's dependencies in fech.gemspec 4 | gemspec -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | fech (1.9.1) 5 | ensure-encoding 6 | fastercsv 7 | people 8 | 9 | GEM 10 | remote: http://rubygems.org/ 11 | specs: 12 | byebug (11.1.3) 13 | diff-lcs (1.5.0) 14 | ensure-encoding (0.2) 15 | fastercsv (1.5.5) 16 | mocha (1.14.0) 17 | people (0.2.1) 18 | psych (4.0.4) 19 | stringio 20 | rake (13.0.6) 21 | rdoc (6.4.0) 22 | psych (>= 4.0.0) 23 | rspec (3.11.0) 24 | rspec-core (~> 3.11.0) 25 | rspec-expectations (~> 3.11.0) 26 | rspec-mocks (~> 3.11.0) 27 | rspec-core (3.11.0) 28 | rspec-support (~> 3.11.0) 29 | rspec-expectations (3.11.0) 30 | diff-lcs (>= 1.2.0, < 2.0) 31 | rspec-support (~> 3.11.0) 32 | rspec-mocks (3.11.1) 33 | diff-lcs (>= 1.2.0, < 2.0) 34 | rspec-support (~> 3.11.0) 35 | rspec-support (3.11.0) 36 | stringio (3.0.2) 37 | webrick (1.7.0) 38 | yard (0.9.27) 39 | webrick (~> 1.7.0) 40 | 41 | PLATFORMS 42 | ruby 43 | 44 | DEPENDENCIES 45 | bundler 46 | byebug 47 | fech! 48 | mocha 49 | rake 50 | rdoc 51 | rspec 52 | yard 53 | 54 | BUNDLED WITH 55 | 1.17.3 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 The New York Times Company 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this library except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | ______ ______ ______ __ 2 | /\ ___\ /\ ___\ /\ ___\ /\ \___ 3 | \ \ __\ \ \ __\ \ \ \____ \ \ __ \ 4 | \ \_\ \ \_____\ \ \_____\ \ \_\ \_\ 5 | \/_/ \/_____/ \/_____/ \/_/\/_/ 6 | 7 | Fech makes it easy to parse electronic campaign finance filings[http://www.fec.gov/finance/disclosure/efile_search.shtml] by candidates, parties and political action committees from the Federal Election Commission. It lets you access filing attributes the same way regardless of filing version, and works as a framework for cleaning and filing data. Fech is an open source project of The New York Times, but contributions from anyone interested in working with F.E.C. filings are greatly appreciated. 8 | 9 | Latest version: 1.8.1. For details see the CHANGELOG. 10 | 11 | Fech works best under Ruby version 2.x, and has been tested under Ruby versions 1.8.7, 1.9.2, 1.9.3, 2.1.2, 2.2.2 and Rubinius. 12 | 13 | == Documentation 14 | 15 | Can be found at Fech's Github page[http://nytimes.github.com/Fech/]. 16 | 17 | == News 18 | 19 | * March 1, 2019: Version 1.8.1 released. Added support for F4T mappings. 20 | * August 19, 2015: Version 1.8 released. Replaced `sources` directory with submodule pulling from [fech-sources](https://github.com/dwillis/fech-sources). 21 | * March 28, 2015: Version 1.7 released. Added support for Schedule SA3L and F3Z transactions, fixed some bugs and updated gems and specs. 22 | * March 11, 2014: Version 1.6.4 released. Bugfix for Schedule E transactions to fix office state and district. 23 | * Jan. 22, 2014: Version 1.6.3 released. Bugfix to ensure Translator object is available to any Filing object. Thanks to @abstrctn for fix. 24 | * Jan. 15, 2014: Version 1.6.2 released. Bugfix to add dissemination date to SE mappings. 25 | * Jan. 15, 2014: Version 1.6.1 released. Bugfix to add FEC version 8.1 mappings for F13 and F24 forms. 26 | * Jan. 14, 2014: Version 1.6.0 released. Added support for FEC electronic filing version 8.1 headers and mappings. 27 | * Nov. 14, 2013: Version 1.5.0 released. Bugfix for F3 mapping that did not include col_a_total_receipts_period. Thanks to @capitolmuckrakr for the report. 28 | * Sep. 10, 2013: Version 1.4.3 released. Bugfix for certain filings that raise encoding errors using Ruby 1.9.3 or greater. 29 | * Sep. 6, 2013: Version 1.4.2 released. Added support for Ruby 2.0 and fixed improper mapping for F1S records. Thanks to @bycoffe for the report. 30 | * May 22, 2013: Version 1.4.1 released. Bugfix to add version 6.2 to F5 filing mappings. 31 | * April 18, 2013: Version 1.4 released. Adds support for unofficial Senate electronic filings. 32 | * March 26, 2013: Version 1.3.2 released. Bugfix for F99 filing encoding issues. Thanks for the patch, @jgillum. 33 | * Dec. 11, 2012: Versions 1.3, 1.3.1 released. Adds support for F13 filings from inaugural committees and fixes an encoding bug. 34 | * Dec. 3, 2012: Version 1.2 released. Fixes encoding errors under Ruby 1.9.3 for ASCII-encoded filings. Thanks to Sanjiv for the bug report. 35 | * Nov. 13, 2012: Version 1.1 released. CSVDoctor skips rows that don't match row type being searched for, which provides a performance boost, and smaller bugfixes for Form 99 handling and date-field conversions. Thanks to Sai for several patches. 36 | * June 16, 2012: Version 1.0.1 released. Bug-fix for older Form 2 support. 37 | * April 11, 2012: Version 1.0.0 released! Support for Ruby 1.9.3 added, all form types supported. 38 | * April 9, 2012: Version 1.0.0.rc1 released. Release candidate with backwards-incompatible change (renaming zip attribute to zip_code). 39 | * March 29, 2012: Version 0.9.10 released. Bug-fix for Form 24 in versions 6.4 and 7.0. 40 | * March 28, 2012: Version 0.9.9 released. Bug-fix to add support for F3XA form type, support for Schedule H and L. 41 | * March 23, 2012: Version 0.9.6 and 0.9.5 released. Bug-fixes for F6 mappings. 42 | * March 10, 2012: Version 0.9.4 released. Added support for F6 filings. 43 | * March 8, 2012: Version 0.9.3 released. Bug-fix for F2 & F24 mappings. 44 | * Feb. 29, 2012: Version 0.9.2 released. Bug-fix for F3 mappings, added filing comparison class. 45 | * Feb. 21, 2012: Versions 0.9.0, 0.9.1 released. Added support for alternative CSV Parsers, F4 filings. 46 | * Feb. 19, 2012: Version 0.8.2 released. Added layouts for F1M and F2 filings. 47 | * Feb. 15, 2012: Version 0.8.1 released. Bug-fix to support F3 termination filings. 48 | * Feb. 13, 2012: Version 0.8.0 released. Layouts for form 3 and form 1 added, for parsing House candidate committee filings. 49 | * Feb. 11, 2012: Version 0.7.0 released. Layouts for form 9 added, for parsing electioneering communications filings. 50 | * Jan. 28, 2012: Version 0.6.0 released. Added support for quoted fields. 51 | * Nov. 22, 2011: Version 0.5.0 released. Layouts for form 3X added, for parsing filings from non-candidate committees. 52 | * Nov. 13, 2011: Version 0.3.0 released. Layouts for forms 24, 5, 56 and 57 added, for parsing independent expenditure filings. 53 | * Nov. 4, 2011: Version 0.2.1 released. Bug-fix release to address a problem with the :include option for selecting only certain columns. Thanks to Aaron Bycoffe for the report and patch. 54 | 55 | == Installation 56 | 57 | Install Fech as a gem: 58 | 59 | gem install fech 60 | 61 | For use in a Rails 3/4 application, put the following in your Gemfile: 62 | 63 | gem 'fech' 64 | 65 | then issue the 'bundle install' command. Fech has been tested under Ruby versions 1.8.7, 1.9.2, 1.9.3, 2.1.2, 2.2.2 and Rubinius. 66 | 67 | == How to contribute 68 | 69 | To develop locally, you'll need to clone this repository and then run the following commands to update the `sources` directory: 70 | 71 | ``` 72 | $ git submodule init 73 | $ git submodule update 74 | ``` 75 | 76 | Fech's goal is to provide support for all electronically filed forms and their row types, so contributors can pick an form type that is currently unsupported and try to implement it, or to improve an existing implementation. For entirely new form types, please include specs showing successful parsing of the summary. A good way to start is to look at the mappings for a similar form type. Please note that Fech currently commits to supporting the F.E.C.'s filing formats back to version 3.0, where applicable. 77 | 78 | Bug reports and feature requests are welcomed by submitting an Issue. Please be advised that development is focused on parsing filings, which may contain errors or be improperly filed, and not on providing wrappers or helper methods for working with filings in another context. 79 | 80 | To get started, fork the repo, make your additions or changes and send a pull request. 81 | 82 | == Pronunciation guide 83 | 84 | It's "fetch", with a soft "ch" sound. There are no other acceptable pronunciations. 85 | 86 | == Authors 87 | 88 | Michael Strickland, michael.strickland@nytimes.com 89 | 90 | Evan Carmi, evan@ecarmi.org 91 | 92 | Aaron Bycoffe, bycoffe@huffingtonpost.com 93 | 94 | Derek Willis, derek.willis@propublica.org 95 | 96 | Daniel Pritchett, daniel@sharingatwork.com 97 | 98 | Sai, sai@makeyourlaws.org 99 | 100 | Jack Gillum, jgillum@ap.org 101 | 102 | == Copyright 103 | 104 | Copyright (c) 2019 The New York Times Company. See LICENSE for details. 105 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | require 'rspec/core/rake_task' 3 | Bundler::GemHelper.install_tasks 4 | Dir.glob('tasks/*.rake').each { |r| import r } 5 | 6 | task :default => :spec 7 | -------------------------------------------------------------------------------- /autotest/discover.rb: -------------------------------------------------------------------------------- 1 | Autotest.add_discovery { "rspec2" } 2 | -------------------------------------------------------------------------------- /fech.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "fech/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "fech" 7 | s.version = Fech::VERSION 8 | s.platform = Gem::Platform::RUBY 9 | s.license = 'Apache-2.0' 10 | s.authors = ["Michael Strickland", "Evan Carmi", "Aaron Bycoffe", "Derek Willis", "Sai"] 11 | s.email = ["dwillis@gmail.com"] 12 | s.homepage = "http://github.com/nytimes/fech" 13 | s.summary = %q{Ruby library for parsing FEC filings.} 14 | s.description = %q{A Ruby library for interacting with electronic filings from the Federal Election Commission.} 15 | 16 | s.rubyforge_project = "fech" 17 | 18 | s.files = `git ls-files`.split("\n") 19 | s.test_files = `git ls-files -- {spec}/*`.split("\n") 20 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 21 | s.require_paths = ["lib"] 22 | 23 | s.add_dependency "fastercsv" 24 | s.add_dependency "people" 25 | s.add_dependency "ensure-encoding" 26 | if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx' 27 | s.add_development_dependency 'rubinius-compiler' 28 | s.add_development_dependency 'rubinius-debugger' 29 | s.add_development_dependency 'rubysl' 30 | s.add_development_dependency 'ffi' 31 | s.add_development_dependency 'psych' 32 | else 33 | if RUBY_VERSION < "1.9" 34 | s.add_development_dependency "linecache", "0.43" 35 | s.add_development_dependency "ruby-debug" 36 | s.add_development_dependency "iconv" 37 | elsif RUBY_VERSION >= "2.0" 38 | s.add_development_dependency "byebug" 39 | elsif RUBY_VERSION >= "1.9" && RUBY_VERSION < '2.0' 40 | s.add_development_dependency "ruby-debug19" 41 | s.add_development_dependency "linecache19" 42 | end 43 | end 44 | s.add_development_dependency "rake" 45 | s.add_development_dependency "rspec" 46 | s.add_development_dependency "mocha" 47 | s.add_development_dependency "bundler" 48 | s.add_development_dependency "rdoc" 49 | s.add_development_dependency "yard" 50 | end 51 | -------------------------------------------------------------------------------- /lib/fech.rb: -------------------------------------------------------------------------------- 1 | require 'fech/filing' 2 | require 'fech/senate_filing' 3 | require 'fech/rendered_maps' 4 | require 'fech/mappings' 5 | require 'fech/default_translations' 6 | require 'fech/translator' 7 | require 'fech/mapped' 8 | require 'fech/fech_utils' 9 | require 'fech/map_generator' 10 | require 'fech/csv' 11 | require 'fech/comparison' 12 | require 'fech/version' 13 | 14 | module Fech 15 | extend FechUtils 16 | DEFAULT_VERSION = "8.4" 17 | end 18 | -------------------------------------------------------------------------------- /lib/fech/comparison.rb: -------------------------------------------------------------------------------- 1 | module Fech 2 | # Fech::Comparison takes two Filing objects and does comparisons on them, 3 | # checking for differences between an original and amended filing, or 4 | # two filings covering the same period in different years. 5 | class Comparison 6 | attr_accessor :filing_1, :filing_2 7 | 8 | # Create a new Comparison object by passing in two Filing objects 9 | # Filing objects need to be downloaded first 10 | # f1 = Fech::Filing.new(767437) 11 | # f1.download 12 | # f2 = Fech::Filing.new(751798) 13 | # f2.download 14 | # comparison = Fech::Comparison.new(f1, f2) 15 | # comparison.summary 16 | def initialize(filing_1, filing_2, opts={}) 17 | @filing_1 = filing_1 18 | @filing_2 = filing_2 19 | end 20 | 21 | # compares summary of this filing with summary of an earlier 22 | # or later version of the filing, returning a Fech::Mapped hash 23 | # of mapped fields whose values have changed. based on rails' hash diff: 24 | # https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/hash/diff.rb 25 | def summary 26 | @filing_1.summary.delete_if { |k, v| @filing_2.summary[k] == v }.merge!(@filing_2.summary.dup.delete_if { |k, v| @filing_1.summary.has_key?(k) }) 27 | end 28 | 29 | # compares a schedule of itemized records from one filing to another 30 | # returns an array of records that are new or have changed. 31 | def schedule(schedule) 32 | @filing_1.rows_like(schedule.to_sym) - @filing_2.rows_like(schedule.to_sym) 33 | end 34 | 35 | end 36 | end -------------------------------------------------------------------------------- /lib/fech/csv.rb: -------------------------------------------------------------------------------- 1 | # Use CSV library included in standard library for Ruby 3.2+ 2 | require 'csv' 3 | 4 | module Fech 5 | class Csv 6 | def self.parse_row(file_path, opts) 7 | ::CSV.foreach(file_path, **opts) { |row| yield row } 8 | end 9 | 10 | def self.clean_opts(opts) 11 | opts.reject {|k,v| ![:col_sep, :quote_char, :encoding].include?(k)} 12 | end 13 | end 14 | 15 | class CsvDoctor < Fech::Csv 16 | def self.parse_row(file_path, opts) 17 | opts[:liberal_parsing] = true 18 | File.open(file_path, "r:#{opts[:encoding]}") do |f| 19 | f.each_line do |line| 20 | next if line.strip.empty? 21 | next if opts.key?(:row_type) && !Fech.regexify(opts[:row_type]).match(line) 22 | 23 | yield safe_line(line, clean_opts(opts)) 24 | end 25 | end 26 | end 27 | 28 | def self.safe_line(line, opts) 29 | begin 30 | ::CSV.parse_line(line, **opts) 31 | rescue ::CSV::MalformedCSVError 32 | row = ::CSV.parse_line(line, liberal_parsing: true, **{**opts, quote_char: "\x00"}) 33 | row.map! { |val| safe_value(val) } 34 | end 35 | end 36 | 37 | def self.safe_value(val) 38 | return val unless val.is_a?(String) 39 | 40 | begin 41 | ::CSV.parse_line(val).first 42 | rescue ::CSV::MalformedCSVError 43 | val 44 | end 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /lib/fech/default_translations.rb: -------------------------------------------------------------------------------- 1 | module Fech 2 | 3 | # Stores sets of build-in translations that can be mixed in to a Fech::Filing. 4 | # Contains functions that accept a Translator, and add arbitrary translations 5 | # to it. The public function names should correspond to the key used to mix it in. 6 | # 7 | # filing = Fech::Filing.new(XXXXXX, :translate => [:names, :dates]) 8 | class DefaultTranslations 9 | 10 | # The five bits that make up a name, and their labels in the People gem 11 | NAME_BITS = [:prefix, :first_name, :middle_name, :last_name, :suffix] 12 | PEOPLE_BITS = [:title, :first, :middle, :last, :suffix] 13 | 14 | attr_reader :t 15 | 16 | def initialize(translator) 17 | @t = translator 18 | end 19 | 20 | # Splits composite names into its component parts, and combines those parts 21 | # into composites where appropriate. Assumes that the canonical names of the 22 | # fields follow the pattern: 23 | # * FIELD_name - "Mr. John Charles Smith Sr." 24 | # * FIELD_prefix - "Mr." 25 | # * FIELD_first_name - "John" 26 | # * FIELD_middle_name - "Charles" 27 | # * FIELD_last_name - "Smith" 28 | # * FIELD_suffix - "Sr." 29 | def names 30 | 31 | # COMBINE split names into composite names for these rows 32 | composites = [ 33 | {:row => :sa, :version => /^[6-8]/, :field => [:contributor, :donor_candidate]}, 34 | {:row => :sb, :version => /^[6-8]/, :field => [:payee, :beneficiary_candidate]}, 35 | {:row => :sc, :version => /^[6-8]/, :field => [:lender, :lender_candidate]}, 36 | {:row => :sc1, :version => /^[6-8]/, :field => [:treasurer, :authorized]}, 37 | {:row => :sc2, :version => /^[6-8]/, :field => :guarantor}, 38 | {:row => :sd, :version => /^[6-8]/, :field => :creditor}, 39 | {:row => :se, :version => /^[6-8]/, :field => [:payee, :candidate]}, 40 | {:row => :sf, :version => /^[6-8]/, :field => [:payee, :payee_candidate]}, 41 | {:row => :f3p, :version => /^[6-8]/, :field => :treasurer}, 42 | {:row => :f3p31, :version => /^[6-8]/, :field => :contributor}, 43 | ] 44 | # SPLIT composite names into component parts for these rows 45 | components = [ 46 | {:row => :sa, :version => /^3|(5.0)/, :field => :contributor}, 47 | {:row => :sa, :version => /^[3-5]/, :field => :donor_candidate}, 48 | {:row => :sb, :version => /^3|(5.0)/, :field => :payee}, 49 | {:row => :sb, :version => /^[3-5]/, :field => :beneficiary_candidate}, 50 | {:row => :sc, :version => /^[3-5]/, :field => [:lender, :lender_candidate]}, 51 | {:row => :sc1, :version => /^[3-5]/, :field => [:treasurer, :authorized]}, 52 | {:row => :sc2, :version => /^[3-5]/, :field => :guarantor}, 53 | {:row => :sd, :version => /^[3-5]/, :field => :creditor}, 54 | {:row => :se, :version => /^[3-5]/, :field => [:payee, :candidate]}, 55 | {:row => :sf, :version => /^[3-5]/, :field => [:payee, :payee_candidate]}, 56 | {:row => :f3p, :version => /^[3-5]/, :field => :treasurer}, 57 | {:row => :f3p31, :version => /^[3-5]/, :field => :contributor}, 58 | ] 59 | 60 | composites.each { |c| combine_components_into_name(c) } 61 | components.each { |c| split_name_into_components(c) } 62 | 63 | end 64 | 65 | # Converts everything that looks like an FEC-formatted date to a 66 | # native Ruby Date object. 67 | def dates 68 | # only convert fields whose name is date* or *_date* 69 | # lots of other things might be 8 digits, and we have to exclude eg 'candidate' 70 | t.convert :field => /(^|_)date/ do |value| 71 | unless value.nil? 72 | Date.parse(value) rescue value 73 | end 74 | end 75 | end 76 | 77 | private 78 | 79 | # Turns "Allred^Ann^Mrs.^III" into "Mrs. Ann Allred III" 80 | def self.fix_carrot_names(name) 81 | name = name.split("^").reverse 82 | # move the suffix to the beginning 83 | name.push name.shift if name.size > 3 84 | name.join(" ") 85 | end 86 | 87 | # Create a Translation for the given row, version named as :field 88 | def combine_components_into_name(composite) 89 | raise ArgumentError, "Must pass a :row, :version AND :field" if composite.nil? 90 | composite[:field] = [composite[:field]] unless composite[:field].is_a?(Array) 91 | 92 | composite[:field].each do |field| 93 | t.combine(:row => composite[:row], :version => composite[:version], 94 | :field => "#{field}_name") do |row| 95 | 96 | # Gather each name_bit from the parsed row, and join it into one value 97 | bits = NAME_BITS.collect do |field_name| 98 | row.send("#{field}_#{field_name}".to_sym) 99 | end 100 | bits.compact.join(" ") 101 | end 102 | end 103 | end 104 | 105 | # Create a Translation for all five name bits, that will strip 106 | # out its respective bit from an already-populate composite name field. 107 | def split_name_into_components(component) 108 | raise ArgumentError, "Must pass a :row, :version AND :field" if component.nil? 109 | component[:field] = [component[:field]] unless component[:field].is_a?(Array) 110 | 111 | component[:field].each do |field| 112 | NAME_BITS.zip(PEOPLE_BITS).each do |field_name, people_name| 113 | t.combine(:row => component[:row], :version => component[:version], 114 | :field => "#{field}_#{field_name}") do |row| 115 | 116 | # Grab the original, composite name 117 | name = row.send("#{field}_name") 118 | 119 | unless name.nil? 120 | # Fix various name formatting errors 121 | name = self.class.fix_carrot_names(name) unless name.index("^").nil? 122 | 123 | # Extract just the component you want 124 | (Fech::Translator::NAME_PARSER.parse(name)[people_name] || "").strip 125 | else 126 | nil 127 | end 128 | end 129 | end 130 | end 131 | end 132 | 133 | end 134 | 135 | end 136 | -------------------------------------------------------------------------------- /lib/fech/fech_utils.rb: -------------------------------------------------------------------------------- 1 | # Contains helper functions and static variables used by various 2 | # Fech classes. 3 | module FechUtils 4 | 5 | # All supported row types pointed to regular expressions that will correctly 6 | # match that row type in the wild. If multiple matches exist, Fech will match 7 | # the longest regex pattern found. 8 | ROW_TYPES = { 9 | :hdr => /^hdr$/i, 10 | :f1 => /^f1[an]/i, 11 | :f13 => /^f13[an]/i, 12 | :f132 => /^f132/i, 13 | :f133 => /^f133/i, 14 | :f1m => /(^f1m[a|n])/i, 15 | :f1s => /^f1s/i, 16 | :f2 => /(^f2$)|(^f2[^4])/i, 17 | :f24 => /(^f24$)|(^f24[an])/i, 18 | :f3 => /^f3[a|n|t]/i, 19 | :f3l => /^f3l[a|n]/i, 20 | :f3p => /(^f3p$)|(^f3p[^s|3])/i, 21 | :f3s => /^f3s/i, 22 | :f3p31 => /^f3p31/i, 23 | :f3ps => /^f3ps/i, 24 | :f3x => /(^f3x$)|(^f3x[ant])/i, 25 | :f3z => /^f3z[t]/i, 26 | :f3z1 => /^f3z1/i, 27 | :f3z2 => /^f3z2/i, 28 | :f4 => /^f4[n|a|t]/i, 29 | :f5 => /^f5[na]/i, 30 | :f56 => /^f56/i, 31 | :f57 => /^f57/i, 32 | :f6 => /(^f6$)|(^f6[an])/i, 33 | :f65 => /^f65/i, 34 | :f7 => /^f7[na]/i, 35 | :f76 => /^f76/i, 36 | :f9 => /^f9/i, 37 | :f91 => /^f91/i, 38 | :f92 => /^f92/i, 39 | :f93 => /^f93/i, 40 | :f94 => /^f94/i, 41 | :f99 => /^f99/i, 42 | :h1 => /^h1/i, 43 | :h2 => /^h2/i, 44 | :h3 => /^h3/i, 45 | :h4 => /^h4/i, 46 | :h5 => /^h5/i, 47 | :h6 => /^h6/i, 48 | :sa => /^sa/i, 49 | :sa3l => /^sa3l/i, 50 | :sb => /^sb/i, 51 | :sc => /^sc[^1-2]/i, 52 | :sc1 => /^sc1/i, 53 | :sc2 => /^sc2/i, 54 | :sd => /^sd/i, 55 | :se => /^se/i, 56 | :sf => /^sf/i, 57 | :sl => /^sl/i, 58 | :text => /^text/i, 59 | } 60 | 61 | # Converts symbols and strings to Regexp objects for use in regex-keyed maps. 62 | # Assumes that symbols should be matched literally, strings unanchored. 63 | # @param [String,Symbol,Regexp] label the object to convert to a Regexp 64 | def regexify(label) 65 | if label.is_a?(Regexp) 66 | Regexp.new(label.source, Regexp::IGNORECASE) 67 | elsif label.is_a?(Symbol) 68 | if ROW_TYPES.keys.include?(label) 69 | ROW_TYPES[label] 70 | else 71 | Regexp.new("^#{label.to_s}$", Regexp::IGNORECASE) 72 | end 73 | else 74 | Regexp.new(Regexp.escape(label.to_s), Regexp::IGNORECASE) 75 | end 76 | end 77 | 78 | 79 | 80 | end 81 | -------------------------------------------------------------------------------- /lib/fech/filing.rb: -------------------------------------------------------------------------------- 1 | require 'tmpdir' 2 | require 'open-uri' 3 | require 'ensure/encoding' 4 | require_relative 'csv' 5 | 6 | module Fech 7 | 8 | # Fech::Filing downloads an Electronic Filing given its ID, and will search 9 | # rows by row type. Using a child Translator object, the data in each row 10 | # is automatically mapped at runtime into a labeled Hash. Additional 11 | # Translations may be added to change the way that data is mapped and cleaned. 12 | class Filing 13 | # first filing number using the version >=3.00 format 14 | # note that there are plenty of opts[:translate]) : nil 28 | @quote_char = opts[:quote_char] || '"' 29 | @resaved = false 30 | @customized = false 31 | @encoding = opts[:encoding] || 'iso-8859-1:utf-8' 32 | end 33 | 34 | # Saves the filing data from the FEC website into the default download 35 | # directory. 36 | def download 37 | File.open(file_path, 'w') do |file| 38 | begin 39 | file << URI.open(filing_url).read 40 | rescue 41 | file << URI.open(filing_url).read.ensure_encoding('UTF-8', :external_encoding => Encoding::UTF_8, 42 | :invalid_characters => :drop) 43 | end 44 | end 45 | self 46 | end 47 | 48 | # Access the header (first) line of the filing, containing information 49 | # about the filing's version and metadata about the software used to file it. 50 | # @return [Hash] a hash that assigns labels to the values of the filing's header row 51 | def header(opts={}) 52 | each_row do |row| 53 | return parse_row?(row) 54 | end 55 | end 56 | 57 | # Access the summary (second) line of the filing, containing aggregate and 58 | # top-level information about the filing. 59 | # @return [Hash] a hash that assigns labels to the values of the filing's summary row 60 | def summary 61 | each_row_with_index do |row, index| 62 | next if index == 0 63 | return parse_row?(row) 64 | end 65 | end 66 | 67 | # Access all lines of the filing that match a given row type. Will return an 68 | # Array of all available lines if called directly, or will yield the mapped 69 | # rows one by one if a block is passed. 70 | # 71 | # @param [String, Regexp] row_type a partial or complete name of the type of row desired 72 | # @option opts [Boolean] :raw should the function return the data as an array 73 | # that has not been mapped to column names 74 | # @option opts [Array] :include list of field names that should be included 75 | # in the returned hash 76 | # @yield [Hash] each matched row's data, as either a mapped hash or raw array 77 | # @return [Array] the complete set of mapped hashes for matched lines 78 | def rows_like(row_type, opts={}, &block) 79 | data = [] 80 | each_row(:row_type => row_type) do |row| 81 | value = parse_row?(row, opts.merge(:parse_if => row_type)) 82 | next if value == false 83 | if block_given? 84 | yield value 85 | else 86 | data << value if value 87 | end 88 | end 89 | block_given? ? nil : data 90 | end 91 | 92 | # Decides what to do with a given row. If the row's type matches the desired 93 | # type, or if no type was specified, it will run the row through #map. 94 | # If :raw was passed true, a flat, unmapped data array will be returned. 95 | # 96 | # @param [String, Regexp] row a partial or complete name of the type of row desired 97 | # @option opts [Array] :include list of field names that should be included 98 | # in the returned hash 99 | def parse_row?(row, opts={}) 100 | return false if row.nil? || row.empty? 101 | 102 | # Always parse, unless :parse_if is given and does not match row 103 | if opts[:parse_if].nil? || \ 104 | Fech.regexify(opts[:parse_if]).match(row.first.downcase) 105 | opts[:raw] ? row : map(row, opts) 106 | else 107 | false 108 | end 109 | end 110 | 111 | # Maps a raw row to a labeled hash following any rules given in the filing's 112 | # Translator based on its version and row type. 113 | # Finds the correct map for a given row, performs any matching Translations 114 | # on the individual values, and returns either the entire dataset, or just 115 | # those fields requested. 116 | # @param [String, Regexp] row a partial or complete name of the type of row desired 117 | # @option opts [Array] :include list of field names that should be included 118 | # in the returned hash 119 | def map(row, opts=nil) 120 | data = Fech::Mapped.new(self, row.first) 121 | full_row_map = map_for(row.first) 122 | 123 | # If specific fields were asked for, return only those 124 | if opts[:include] 125 | row_map = full_row_map.select { |k| opts[:include].include?(k) } 126 | else 127 | row_map = full_row_map 128 | end 129 | 130 | # Inserts the row into data, performing any specified preprocessing 131 | # on individual cells along the way 132 | row_map.each_with_index do |field, index| 133 | value = row[full_row_map.index(field)] 134 | if translator 135 | translator.get_translations(:row => row.first, 136 | :version => filing_version, :action => :convert, 137 | :field => field).each do |translation| 138 | # User's Procs should be given each field's value as context 139 | value = translation[:proc].call(value) 140 | end 141 | end 142 | data[field] = value 143 | end 144 | 145 | # Performs any specified group preprocessing / combinations 146 | if translator 147 | combinations = translator.get_translations(:row => row.first, 148 | :version => filing_version, :action => :combine) 149 | row_hash = hash_zip(row_map, row) if combinations 150 | combinations.each do |translation| 151 | # User's Procs should be given the entire row as context 152 | value = translation[:proc].call(row_hash) 153 | field = translation[:field].source.gsub(/[\^\$]*/, "").to_sym 154 | data[field] = value 155 | end 156 | end 157 | data 158 | end 159 | 160 | # Returns the column names for given row type and the filing's version 161 | # in the order they appear in row data. 162 | # @param [String, Regexp] row_type representation of the row desired 163 | def map_for(row_type) 164 | mappings.for_row(row_type) 165 | end 166 | 167 | # Returns the column names for given row type and version in the order 168 | # they appear in row data. 169 | # @param [String, Regexp] row_type representation of the row desired 170 | # @option opts [String, Regexp] :version representation of the version desired 171 | def self.map_for(row_type, opts={}) 172 | Fech::Mappings.for_row(row_type, opts) 173 | end 174 | 175 | # Accessor for @translator. Will return the Translator initialized in 176 | # Filing's initializer if built-in translations were passed to Filing's 177 | # initializer ({:translate => [:foo, :bar]}). 178 | # Otherwise, will create and memoize a new Translator without any default 179 | # translations. 180 | def translator 181 | @translator ||= Fech::Translator.new 182 | end 183 | 184 | # @yield [t] returns a reference to the filing's Translator 185 | # @yieldparam [Translator] the filing's Translator 186 | def translate(&block) 187 | if block_given? 188 | yield translator 189 | else 190 | translator 191 | end 192 | end 193 | 194 | # Whether this filing amends a previous filing or not. 195 | def amendment? 196 | !amends.nil? 197 | end 198 | 199 | # Returns the filing ID of the past filing this one amends, 200 | # nil if this is a first-draft filing. 201 | # :report_id in the HDR line references the amended filing 202 | def amends 203 | header[:report_id] 204 | end 205 | 206 | # Combines an array of keys and values into an Fech::Mapped object, 207 | # a type of Hash. 208 | # @param [Array] keys the desired keys for the new hash 209 | # @param [Array] values the desired values for the new hash 210 | # @return [Fech::Mapped, Hash] 211 | def hash_zip(keys, values) 212 | Fech::Mapped.new(self, values.first).merge(Hash[*keys.zip(values).flatten]) 213 | end 214 | 215 | # The version of the FEC software used to generate this Filing 216 | def filing_version 217 | @filing_version ||= parse_filing_version 218 | end 219 | 220 | # Pulls out the version number from the header line. 221 | # Must parse this line manually, since we don't know the version yet, and 222 | # thus the delimiter type is still a mystery. 223 | def parse_filing_version 224 | first = File.open(file_path).first 225 | if first.index("\034").nil? 226 | ::CSV.parse(first).flatten[2] 227 | else 228 | ::CSV.parse(first, col_sep: "\034").flatten[2] 229 | end 230 | end 231 | 232 | # Only FEC format 3.00 + is supported 233 | def readable? 234 | filing_version.to_i >= 3 235 | end 236 | 237 | # Gets or creats the Mappings instance for this filing_version 238 | def mappings 239 | @mapping ||= Fech::Mappings.new(filing_version) 240 | end 241 | 242 | # The location of the Filing on the file system 243 | def file_path 244 | File.join(download_dir, file_name) 245 | end 246 | 247 | # The raw contents of the Filing 248 | def file_contents 249 | File.open(file_path, "r:#{@encoding}") 250 | end 251 | 252 | # Determine the form type of the filing 253 | # before it's been parsed. This is needed 254 | # for the F99 special case. 255 | def form_type 256 | 257 | if RUBY_VERSION >= "2.0" 258 | lines = file_contents.each_line 259 | else 260 | lines = file_contents.lines 261 | end 262 | 263 | lines.each_with_index do |row, index| 264 | next if index == 0 265 | return row.split(delimiter).first 266 | end 267 | end 268 | 269 | # The file path where custom versions 270 | # of a filing are to be saved. 271 | def custom_file_path 272 | File.join(download_dir, "fech_#{file_name}") 273 | end 274 | 275 | # Handle the contents of F99s by removing the 276 | # [BEGINTEXT] and [ENDTEXT] delimiters and 277 | # putting the text content onto the same 278 | # line as the summary. 279 | def fix_f99_contents 280 | @customized = true 281 | content = file_contents.read 282 | 283 | if RUBY_VERSION > "1.9.2" 284 | content.encode!('UTF-16', 'UTF-8', :invalid => :replace, :undef => :replace, :replace => '?') 285 | content.encode!('UTF-8', 'UTF-16') 286 | else 287 | require 'iconv' 288 | ic = Iconv.new('UTF-8//IGNORE', 'UTF-8') 289 | content = ic.iconv(content + ' ')[0..-2] # add valid byte before converting, then remove it 290 | end 291 | 292 | regex = /\n\[BEGINTEXT\]\n(.*?)\[ENDTEXT\]\n/mi # some use eg [EndText] 293 | match = content.match(regex) 294 | if match 295 | repl = match[1].gsub(/"/, '""') 296 | content.gsub(regex, "#{delimiter}\"#{repl}\"") 297 | else 298 | content 299 | end 300 | end 301 | 302 | # Resave the "fixed" version of an F99 303 | def resave_f99_contents 304 | return true if @resaved 305 | File.open(custom_file_path, 'w') { |f| f.write(fix_f99_contents) } 306 | @resaved = true 307 | end 308 | 309 | def file_name 310 | "#{filing_id}.fec" 311 | end 312 | 313 | def filing_url 314 | "https://docquery.fec.gov/dcdev/posted/#{filing_id}.fec" 315 | end 316 | 317 | # Iterates over and yields the Filing's lines 318 | # @option opts [Boolean] :with_index yield both the item and its index 319 | # @option opts [Boolean] :row_type yield only rows that match this type 320 | # @yield [Array] a row of the filing, split by the delimiter from #delimiter 321 | def each_row(opts={}, &block) 322 | unless File.exist?(file_path) 323 | raise "File #{file_path} does not exist. Try invoking the .download method on this Filing object." 324 | end 325 | 326 | # If this is an F99, we need to parse it differently. 327 | resave_f99_contents if ['F99', '"F99"'].include? form_type 328 | 329 | c = 0 330 | ::CSV.foreach(@customized ? customized : file_path, **{col_sep: delimiter, quote_char: @quote_char, skip_blanks: true, encoding: @encoding, liberal_parsing: true}) do |row| 331 | if opts[:with_index] 332 | yield [row, c] 333 | c += 1 334 | else 335 | yield row 336 | end 337 | end 338 | end 339 | 340 | # Wrapper around .each_row to include indexes 341 | def each_row_with_index(&block) 342 | each_row(:with_index => true, &block) 343 | end 344 | 345 | # @return [String] the delimiter used in the filing's version 346 | def delimiter 347 | filing_version.to_f < 6 ? "," : "\034" 348 | end 349 | 350 | end 351 | end 352 | -------------------------------------------------------------------------------- /lib/fech/map_generator.rb: -------------------------------------------------------------------------------- 1 | module Fech 2 | 3 | # Helper class to generate mapping hashes from source csv data. 4 | # Needed to rebuild rendered_maps.rb with new source data, not used 5 | # in main gem. 6 | # rake fech:maps 7 | class MapGenerator 8 | 9 | attr_accessor :map 10 | PAPER_FILING_VERSIONS = ["3.1", "3.0", "2.6", "2.4", "2.3", "2.2", "1.0"] 11 | PAPER_BASE_ROW_TYPES = ["HDR", "F3", "F3X", "SchA", "SchB"] 12 | 13 | FILING_VERSIONS = ["8.4","8.3","8.2", "8.1", "8.0", "7.0", "6.4", "6.3", "6.2", "6.1", 14 | "5.3", "5.2", "5.1", "5.0", "3"] 15 | BASE_ROW_TYPES = ["HDR", "F1", "F13", "F132", "F133", "F1M", "F1S", "F2", "F24", "F3", "F3L", "F3P", "F3P31", "F3PS", 16 | "F3S", "F3X", "F3Z", "F3Z1", "F3Z2", "F4", "F5", "F56", "F57", "F6", "F65", "F7", "F76", "F9", "F91", "F92", "F93", 17 | "F94", "F99", "H1", "H2", "H3", "H4", "H5", "H6", 18 | "SchA", "SchA3L", "SchB", "SchC", "SchC1", "SchC2", "SchD", "SchE", "SchF", "SchL", "TEXT"] 19 | ROW_TYPE_MATCHERS = { 20 | "HDR" => FechUtils::ROW_TYPES[:hdr], 21 | "F1" => FechUtils::ROW_TYPES[:f1], 22 | "F13" => FechUtils::ROW_TYPES[:f13], 23 | "F132" => FechUtils::ROW_TYPES[:f132], 24 | "F133" => FechUtils::ROW_TYPES[:f133], 25 | "F1M" => FechUtils::ROW_TYPES[:f1m], 26 | "F1S" => FechUtils::ROW_TYPES[:f1s], 27 | "F2" => FechUtils::ROW_TYPES[:f2], 28 | "F24" => FechUtils::ROW_TYPES[:f24], 29 | "F3" => FechUtils::ROW_TYPES[:f3], 30 | "F3L" => FechUtils::ROW_TYPES[:f3l], 31 | "F3P" => FechUtils::ROW_TYPES[:f3p], 32 | "F3S" => FechUtils::ROW_TYPES[:f3s], 33 | "F3P31" => FechUtils::ROW_TYPES[:f3p31], 34 | "F3PS" => FechUtils::ROW_TYPES[:f3ps], 35 | "F3X" => FechUtils::ROW_TYPES[:f3x], 36 | "F3Z" => FechUtils::ROW_TYPES[:f3z], 37 | "F3Z1" => FechUtils::ROW_TYPES[:f3z1], 38 | "F3Z2" => FechUtils::ROW_TYPES[:f3z2], 39 | "F4" => FechUtils::ROW_TYPES[:f4], 40 | "F5" => FechUtils::ROW_TYPES[:f5], 41 | "F56" => FechUtils::ROW_TYPES[:f56], 42 | "F57" => FechUtils::ROW_TYPES[:f57], 43 | "F6" => FechUtils::ROW_TYPES[:f6], 44 | "F65" => FechUtils::ROW_TYPES[:f65], 45 | "F7" => FechUtils::ROW_TYPES[:f7], 46 | "F76" => FechUtils::ROW_TYPES[:f76], 47 | "F9" => FechUtils::ROW_TYPES[:f9], 48 | "F91" => FechUtils::ROW_TYPES[:f91], 49 | "F92" => FechUtils::ROW_TYPES[:f92], 50 | "F93" => FechUtils::ROW_TYPES[:f93], 51 | "F94" => FechUtils::ROW_TYPES[:f94], 52 | "F99" => FechUtils::ROW_TYPES[:f99], 53 | "H1" => FechUtils::ROW_TYPES[:h1], 54 | "H2" => FechUtils::ROW_TYPES[:h2], 55 | "H3" => FechUtils::ROW_TYPES[:h3], 56 | "H4" => FechUtils::ROW_TYPES[:h4], 57 | "H5" => FechUtils::ROW_TYPES[:h5], 58 | "H6" => FechUtils::ROW_TYPES[:h6], 59 | "SchA" => FechUtils::ROW_TYPES[:sa], 60 | "SchA3L" => FechUtils::ROW_TYPES[:sa3l], 61 | "SchB" => FechUtils::ROW_TYPES[:sb], 62 | "SchC" => FechUtils::ROW_TYPES[:sc], 63 | "SchC1" => FechUtils::ROW_TYPES[:sc1], 64 | "SchC2" => FechUtils::ROW_TYPES[:sc2], 65 | "SchD" => FechUtils::ROW_TYPES[:sd], 66 | "SchE" => FechUtils::ROW_TYPES[:se], 67 | "SchF" => FechUtils::ROW_TYPES[:sf], 68 | "SchL" => FechUtils::ROW_TYPES[:sl], 69 | "TEXT" => FechUtils::ROW_TYPES[:text], 70 | } 71 | 72 | # Goes through all version header summary files and generates 73 | # row map files for each type of row inside them. 74 | def self.convert_header_file_to_row_files(source_dir) 75 | data = {} 76 | hybrid_data = {} 77 | 78 | ignored_fields = File.open(ignored_fields_file(source_dir)).readlines.map { |l| l.strip } 79 | 80 | # Create a hash of data with an entry for each row type found in the source 81 | # version summary files. Each row has an entry for each version map that 82 | # exists for it. If maps for two different versions are identical, they 83 | # are combined. 84 | FILING_VERSIONS.each do |version| 85 | filepath = version_summary_file(source_dir, version) 86 | 87 | # Clean the source files by removing unparseable characters 88 | if RUBY_VERSION < "1.9.3" 89 | require 'iconv' 90 | ic = Iconv.new('UTF-8//IGNORE', 'UTF-8') 91 | valid_string = ic.iconv(open(filepath).read << ' ')[0..-2] 92 | else 93 | valid_string = (open(filepath).read << ' ')[0..-2].encode!('UTF-16', 'UTF-8', :invalid => :replace, :replace => '') 94 | valid_string = valid_string.encode!('UTF-8', 'UTF-16') 95 | end 96 | open(filepath, 'w').write(valid_string) 97 | 98 | Fech::Csv.foreach(filepath) do |row| 99 | # Each row of a version summary file contains the ordered list of 100 | # column names. 101 | data[row.first] ||= {} 102 | hybrid_data[row.first] ||= {} 103 | row_version_data = remove_ignored_fields(row, ignored_fields) 104 | 105 | # Check the maps for this row type in already-processed versions. 106 | # If this map is identical to a previous map, tack this version on to 107 | # to it instead of creating a new one. 108 | data[row.first][version] = row_version_data 109 | data[row.first].each do |k, v| 110 | # skip the row we just added 111 | 112 | next if k == version 113 | if v == row_version_data 114 | # Create the new hybrid entry 115 | hybrid_data[row.first]["#{k}|#{version}"] = row_version_data 116 | 117 | # Delete the old entry, and the one for this version only 118 | data[row.first].delete(k) 119 | data[row.first].delete(version) 120 | end 121 | end 122 | data[row.first].update(hybrid_data[row.first]) 123 | end 124 | end 125 | 126 | # Go through each row type and create a base map management file that 127 | # will serve as a template for organizing which fields are the same 128 | # between versions. This file will need to then be arranged by hand to 129 | # clean up the data. Each row will represent a column across versions, 130 | # each column a unique map for that row for one or more versions. 131 | data.each do |row_type, row_data| 132 | file_path = write_row_map_file(source_dir, row_type) 133 | next unless File.exist?(file_path) 134 | File.open(file_path, 'w') do |f| 135 | f.write('canonical') 136 | 137 | to_transpose = [] 138 | row_data.sort.reverse.each do |version, version_data| 139 | to_transpose << ["^#{version}", version_data.each_with_index.collect {|x, idx| idx+1}].flatten 140 | to_transpose << [nil, version_data].flatten 141 | end 142 | 143 | # standardize row size 144 | max_size = to_transpose.max { |r1, r2| r1.size <=> r2.size }.size 145 | to_transpose.each { |r| r[max_size - 1] ||= nil } 146 | transposed = to_transpose.transpose 147 | 148 | transposed.each do |transposed_data| 149 | transposed_data.collect! {|x| x.to_s.gsub(/\r/, ' ')} 150 | canonical = transposed_data[1] # first description 151 | if canonical 152 | canonical = canonical.gsub(/\{.*\}/, "").gsub(/[ -\.\/\(\)]/, "_").gsub(/_+/, "_").gsub(/(_$)|(^_)/, "").downcase 153 | transposed_data = [canonical, transposed_data].flatten 154 | end 155 | f.write(transposed_data.join(',')) 156 | f.write("\n") 157 | end 158 | end 159 | end 160 | 161 | end 162 | 163 | # Generates the mapping for each row type in BASE_ROW_TYPES, writes them out 164 | # to file for inclusion in the gem. 165 | def self.dump_row_maps_to_ruby(source_dir, file_path) 166 | File.open(file_path, 'w') do |f| 167 | f.write("# Generated automatically by Fech::MapGenerator.\n\n") 168 | f.write("# RENDERED_MAPS contains an entry for each supported row type, which in turn:\n") 169 | f.write("# contain an entry for each distinct map between a row's labels and the\n") 170 | f.write("# indexes where their values can be found.\n") 171 | f.write("module Fech\n") 172 | f.write(" RENDERED_MAPS = {\n") 173 | BASE_ROW_TYPES.each do |row_type| 174 | f.write(" \"#{ROW_TYPE_MATCHERS[row_type].source}\" => {\n") 175 | generate_row_map_from_file(source_dir, row_type).sort_by(&:first).reverse.each do |k, v| 176 | f.write(" \'#{k}' => [#{v.map {|x| x.to_s.gsub(/^\d+_?/, "") }.collect {|x| (x.nil? || x == "") ? "nil" : ":#{x}" }.join(', ') }],\n") 177 | end 178 | f.write(" },\n") 179 | end 180 | f.write(" }\n") 181 | f.write("end") 182 | end 183 | end 184 | 185 | # For a given row type, parses its source file and returns 186 | # a mapping object for it. 187 | def self.generate_row_map_from_file(source_dir, row_type) 188 | versions = [] 189 | version_indexes = [] 190 | data = {} 191 | text = open(row_map_file(source_dir, row_type)).read 192 | split_char = text.index(/\r/) ? /\r/ : /\n/ 193 | rows = text.split(split_char).collect {|x| x.split(',')} 194 | rows.each do |row| 195 | row = row.collect {|x| x.gsub("\n", "")} 196 | if row.first.nil? 197 | require 'ruby-debug'; debugger 198 | end 199 | if row.first.downcase == "canonical" 200 | versions = row[1..-1].uniq.collect {|x| x unless (x.nil? || x.empty?)}.compact 201 | row.each_with_index {|x, ind| version_indexes << ind unless (x.nil? || x.empty?)}.slice!(1) 202 | version_indexes.slice!(0, 1) 203 | versions.each {|x| data[x] = [] } 204 | 205 | elsif row.first.size > 0 206 | canonical = row.first 207 | 208 | versions.zip(version_indexes).each do |version, row_index| 209 | index = row[row_index] 210 | data[version][index.to_i - 1] = canonical.to_sym if index.to_i > 0 211 | end 212 | end 213 | end 214 | 215 | row_map = {} 216 | data.each {|key, value| row_map[key] = value} 217 | row_map 218 | end 219 | 220 | # Remove both the row type from the beginning of the row, 221 | # and any fields marked as "ignore" in sources/headers/ignore.csv 222 | def self.remove_ignored_fields(row, ignore) 223 | data = row[1..-1].compact # strip off the row type 224 | data.reject { |f| ignore.include?(f) } 225 | end 226 | 227 | def self.row_map_file(source_dir, row_type) 228 | File.join(source_dir, row_type + '.csv') 229 | end 230 | 231 | def self.ignored_fields_file(source_dir) 232 | File.join(source_dir, 'headers', 'ignore.csv') 233 | end 234 | 235 | def self.version_summary_file(source_dir, version) 236 | File.join(source_dir, 'headers', version + '.csv') 237 | end 238 | 239 | def self.write_row_map_file(source_dir, row_type) 240 | File.join(source_dir, 'rows', row_type + '.csv') 241 | end 242 | 243 | end 244 | end 245 | -------------------------------------------------------------------------------- /lib/fech/mapped.rb: -------------------------------------------------------------------------------- 1 | module Fech 2 | 3 | # Fech::Mapped is a thin wrapper around Hash which allows values to be 4 | # referenced either by key or by an alias specified in the associated 5 | # Filing's Translations. 6 | class Mapped < Hash 7 | 8 | attr_accessor :filing, :row_type 9 | alias :old_bracket :[] 10 | 11 | def initialize(filing, row_type) 12 | @filing = filing 13 | @row_type = row_type 14 | end 15 | 16 | # Just calls Hash's [] method, unless the specified key doesn't 17 | # exist, in which case it checks for any aliases on the filing's 18 | # translator. 19 | def [](key, &block) 20 | if has_key?(key) 21 | old_bracket(key, &block) 22 | else 23 | # Look up aliases in reverse, to find the most recent one 24 | # Does not allow (obvious) recursion 25 | aliias = filing.translator.aliases.reverse.detect do |a| 26 | a[:alias] == key && a[:row].match(row_type) && a[:alias] != a[:for] 27 | end 28 | # Pass the key this alias references back to this function 29 | aliias ? old_bracket(aliias[:for], &block) : nil 30 | end 31 | end 32 | 33 | def method_missing(method, *args, &block) 34 | self[method] 35 | end 36 | 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/fech/mappings.rb: -------------------------------------------------------------------------------- 1 | module Fech 2 | class VersionError < RuntimeError; end 3 | 4 | # Fech::Mappings loads a set of master mappings between labels and where 5 | # their values can be found in Electronic Filings for various row types 6 | # and versions. 7 | # To access a map, call Mappings.for_row with the row_type, 8 | # and optionally the version: 9 | # Mappings.for_row("SA", :version => 6.1) 10 | class Mappings 11 | 12 | attr_accessor :map, :version 13 | 14 | def initialize(ver = Fech::DEFAULT_VERSION) 15 | @version = ver 16 | @map = load_map 17 | @cache = {} 18 | end 19 | 20 | # Returns a hash of mappings for row with given row_type 21 | # 22 | # @param [String,Symbol] row_type the row type whose map to find 23 | def for_row(row_type) 24 | @cache[row_type] ||= self.class.for_row(row_type, :version => @version) 25 | end 26 | 27 | # Returns the basic, default mappings hash by reading in a mappings 28 | # file and saving the variable to the class's context. 29 | def load_map 30 | self.class.load_map 31 | end 32 | 33 | def self.load_map 34 | Fech::RENDERED_MAPS 35 | end 36 | 37 | # Given a row type, first find the entire block of maps for that row type. 38 | # Then, use the filing's version to choose which specific map set to use, 39 | # and return it. 40 | # 41 | # @param [Symbol,String,Regex] row_type the row whose map to find 42 | def self.for_row(row_type, opts={}) 43 | opts[:version] ||= Fech::DEFAULT_VERSION 44 | map = key_by_regex(load_map, row_type) 45 | key_by_regex(map, opts[:version]) 46 | end 47 | 48 | # Given a Hash whose keys are string representations of regular expressions, 49 | # return the value whose key best matches the given label. 50 | # 51 | # @param [Hash] hash a Hash with string regular expressions for keys 52 | # @param [String,Symbol,Regexp] label return the key that best matches this 53 | def self.key_by_regex(hash, label) 54 | label = label.source if label.is_a?(Regexp) 55 | 56 | # Try matching longer keys first, to ensure more accurate keys are 57 | # prioritized over less accurate ones. 58 | hash.keys.sort { |x, y| x.length <=> y.length }.reverse.each do |key| 59 | return hash[key] if Regexp.new(key, Regexp::IGNORECASE).match(label.to_s) 60 | end 61 | 62 | raise VersionError, "Attempted to access mapping that has not been generated (#{label}). " + 63 | "Supported keys match the format: #{hash.keys.join(', ')}" 64 | end 65 | 66 | end 67 | end 68 | -------------------------------------------------------------------------------- /lib/fech/senate_filing.rb: -------------------------------------------------------------------------------- 1 | module Fech 2 | class SenateFiling < Filing 3 | def filing_url 4 | "https://docquery.fec.gov/senate/posted/#{filing_id}.fec" 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/fech/translator.rb: -------------------------------------------------------------------------------- 1 | require 'people' 2 | 3 | module Fech 4 | 5 | # Fech::Translator stores a collection of Procs which are associated with 6 | # one or many field types, row types and filing versions. When a row that 7 | # matches all of these is mapped in Filing, the Proc is run on that value. 8 | # 9 | # :action => :convert alters a single value in place. 10 | # :combine creates a new row out of others. 11 | # 12 | # It also stores a set of aliases, allowing fields on the returned Hash of 13 | # mapped data to be accessed by other names. 14 | class Translator 15 | 16 | attr_accessor :translations, :aliases, :cache 17 | 18 | NAME_PARSER = People::NameParser.new 19 | 20 | def initialize(opts = {}) 21 | @cache = {} 22 | @aliases = [] 23 | @translations = [] 24 | # op-in default translation packs 25 | add_default_translations(opts[:include] || []) 26 | end 27 | 28 | # Returns list of all translations that should be applied to values of 29 | # specified row and field. 30 | # 31 | # @option opts [String] :field the current field's value 32 | # @option opts [String] :version the current filing's version 33 | # @option opts [String] :row the row type 34 | # @option opts [Symbol] :action match only :combine or :convert translations 35 | def get_translations(opts) 36 | key = [:field, :row, :version, :action].collect { |key| opts[key] }.join(":") 37 | @cache[key] ||= \ 38 | procs = translations.collect do |t| 39 | t if self.class.applicable_translation?(t, opts) 40 | end.compact 41 | end 42 | 43 | # Given a translation and any or all of field, version, row, action: 44 | # Returns true if all the given options are compatible with those 45 | # specified in the translation. 46 | # 47 | # @param [Hash] translation the translation being tested for relevance 48 | # @option opts [String] :field the current field's value 49 | # @option opts [String] :version the current filing's version 50 | # @option opts [String] :row the row type 51 | # @option opts [Symbol] :action match only :combine or :convert translations 52 | def self.applicable_translation?(translation, opts) 53 | opts.keys.all? { |k| translation[k].match(opts[k].to_s) } 54 | end 55 | 56 | # Adds a tranlation for preprocessing a single field's value 57 | # 58 | # t.convert(:row => /^sa/, :field => :date_coverage_from) { |v| Date.parse(v) } 59 | # 60 | # @option opts [String] :field the current field's value 61 | # @option opts [String] :version the current filing's version 62 | # @option opts [String] :row the row type 63 | def convert(args={}, &block) 64 | add_translation(args.merge(:action => :convert), &block) 65 | end 66 | 67 | # Adds a translation that uses other fields to create a new one 68 | # 69 | # t.combine(:row => "sa", :field => :net_individual_contributions) do |row| 70 | # row.individual_contributions - row.individual_refunds 71 | # end 72 | # 73 | # @option opts [String] :field the name of the field to create 74 | # @option opts [String] :version the current filing's version 75 | # @option opts [String] :row the row type 76 | def combine(args={}, &block) 77 | add_translation(args.merge(:action => :combine), &block) 78 | end 79 | 80 | # Allows @old_name on @row to be accessible on the returned hash as @new_name 81 | # 82 | # t.alias(:new, :old, "sa") 83 | # 84 | # @param [Symbol] new_name the given field will be accessible using this token 85 | # @param [Symbol] old_name the existing field whose value to alias 86 | # @param [Symbol,Regex] row the types of rows this alias should be applied to 87 | def alias(new_name, old_name, row=/.*/) 88 | aliases << { 89 | :row => Fech.regexify(row), 90 | :alias => new_name, 91 | :for => old_name 92 | } 93 | end 94 | 95 | private 96 | 97 | # Adds a translation to the global translation list. 98 | # Åt runtime, any field whose field, row and version match a translation 99 | # will have its value preprocessed through &block. 100 | # 101 | # @option data [String] :field the current field's value 102 | # @option data [String] :version the current filing's version 103 | # @option data [String] :row the row type 104 | def add_translation(data, &block) 105 | raise "Block required" unless block_given? 106 | 107 | # The cache may be now be out of date after adding this translation 108 | cache = {} 109 | 110 | data ||= {} 111 | data[:row] ||= /.*/ 112 | data[:field] ||= /.*/ 113 | data[:version] ||= /.*/ 114 | 115 | # Convert any string or symbols to regular expressions for the hash 116 | data.each do |k,v| 117 | data[k] = Fech.regexify(v) 118 | end 119 | 120 | data = data.merge(:proc => block) 121 | translations << data 122 | data 123 | end 124 | 125 | # For each default translation set given, execute the corresponding 126 | # code in Fech::DefaultTranslations. 127 | def add_default_translations(translations_list) 128 | translations_list = [translations_list] unless translations_list.is_a?(Array) 129 | return if translations_list.empty? 130 | 131 | default = Fech::DefaultTranslations.new(self) 132 | translations_list.each do |package| 133 | default.send(package) 134 | end 135 | end 136 | 137 | end 138 | end -------------------------------------------------------------------------------- /lib/fech/version.rb: -------------------------------------------------------------------------------- 1 | module Fech 2 | VERSION = "2.0" 3 | end 4 | -------------------------------------------------------------------------------- /spec/comparison_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Fech::Comparison do 4 | 5 | describe "compare" do 6 | before do 7 | @amended_filing = Fech::Filing.new(767339) 8 | @amended_filing.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '767339.fec')) 9 | @original_filing = Fech::Filing.new(467627) 10 | @original_filing.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '467627.fec')) 11 | @comparison = Fech::Comparison.new(@amended_filing, @original_filing) 12 | end 13 | 14 | it "should return a hash of columns and values that have changed for two filings" do 15 | @comparison.summary.class.should == Fech::Mapped 16 | @comparison.summary[:col_a_net_contributions].should == "542344.49" 17 | end 18 | 19 | it "should return an array of schedule items that have changed" do 20 | @comparison.schedule(:sa).size.should == 576 21 | @comparison.schedule("sb").size.should == 60 22 | end 23 | 24 | it "should return an empty array of schedule items when none have changed" do 25 | @comparison.schedule("sc").size.should == 0 26 | end 27 | 28 | end 29 | 30 | end -------------------------------------------------------------------------------- /spec/csv_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Fech::Csv do 4 | 5 | before do 6 | @filing = Fech::Filing.new(723604, :csv_parser => Fech::CsvDoctor) 7 | @filing.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '723604.fec')) 8 | end 9 | 10 | it "should parse a filing using CsvDoctor" do 11 | @filing.rows_like(//) { |row| nil } 12 | end 13 | 14 | end 15 | -------------------------------------------------------------------------------- /spec/data/1247604.fec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwillis/Fech/b5a07597d6ef398266b0f4f82cda424141d213ad/spec/data/1247604.fec -------------------------------------------------------------------------------- /spec/data/425925.fec: -------------------------------------------------------------------------------- 1 | HDRFEC6.4Synetech LLC2.0 2 | F13NC00458166PRESIDENTIAL INAUGURAL COMMITTEE 2009607 14th St NWSuite 700WashingtonDC2000590S200904062009070554277443.931034875.8453242568.09FoucartBrian20090720 3 | F132C00458166250262INDHendersonHelenLee3100 R St NWWashingtonDC2000729372009052250000.0050000.00 4 | F133C00458166R111751INDDettelbachSteven13900 Shaker BlvdApartment 1014ClevelandOH441201587200905152000.00Credit Card Chargeback 5 | F133C00458166R186632INDMazlishAnthony5706 Surrey StChevy ChaseMD208155520200904062000.00Credit Card Chargeback 6 | F133C00458166R187963INDMichelsohnMichelle299 Riverside Dr Apt 6ANew YorkNY100255289200904061000.00Credit Card Chargeback 7 | F133C00458166R188307INDMosenaDavid5646 S Kimbark AveChicagoIL60637160620090421600.00Credit Card Chargeback 8 | F133C00458166R188369INDMosenaLea5646 S Kimbark AveChicagoIL60637160620090421600.00Credit Card Chargeback 9 | F133C00458166R188281INDMosenaPat5646 S Kimbark AveChicagoIL60637160620090421600.00Credit Card Chargeback 10 | F133C00458166R188326INDMosenaPat5646 S Kimbark AveChicagoIL60637160620090421600.00Credit Card Chargeback 11 | F133C00458166R188410INDMosenaPat5646 S Kimbark AveChicagoIL60637160620090421600.00Credit Card Chargeback 12 | F133C00458166R122643INDMursteinAileen86 Glen Cove RdRoslyn HeightsNY11577171820090409100.00Credit Card Chargeback 13 | F133C00458166R123103INDMursteinAileen86 Glen Cove RdRoslyn HeightsNY11577171820090409100.00Credit Card Chargeback 14 | F133C00458166R188553INDShakespeareSandra6700 S South Shore DrChicagoIL60649131020090423750.00Credit Card Chargeback 15 | F133C00458166R188619INDShakespeareSandra6700 S South Shore DrChicagoIL60649131020090423750.00Credit Card Chargeback 16 | F133C00458166R188644INDShakespeareSandra6700 S South Shore DrChicagoIL60649131020090423750.00Credit Card Chargeback 17 | F133C00458166R188716INDShakespeareSandra6700 S South Shore DrChicagoIL60649131020090423750.00Credit Card Chargeback 18 | F133C00458166R188763INDShakespeareSandra6700 S South Shore DrChicagoIL60649131020090423750.00Credit Card Chargeback 19 | F133C00458166R188764INDShakespeareSandra6700 S South Shore DrChicagoIL60649131020090423750.00Credit Card Chargeback 20 | F133C00458166R188767INDShakespeareSandra6700 S South Shore DrChicagoIL60649131020090423750.00Credit Card Chargeback 21 | F133C00458166R188654INDSwansonBurton3407 Mill Creek Ct Unit 2ChampaignIL61822820120090410300.00Credit Card Chargeback 22 | F133C00458166R134172INDWallerRose645 El Dorado Ave Apt 211OaklandCA94611506620090704400.00Contribution Refund 23 | F133C00458166R136223INDWaylandAlexandra3301 NE 5th Ave#1103MiamiFL33137405320090612800.00Credit Card Chargeback 24 | F133C00458166R188140INDWilsonJoycelyn9952 Royal Commerce PlUpper MarlboroMD20774116320090512450.00Credit Card Chargeback 25 | -------------------------------------------------------------------------------- /spec/data/723604.fec: -------------------------------------------------------------------------------- 1 | HDRFEC7.0CMDI FEC FILER8.1.1 2 | F3PNC00494393"Pawlenty for President Exploratory Committee""One Financial Plaza""120 South Sixth Street, 9th Floor""Minneapolis"MN55402XQ1P2012201211052011010120110331"Kennedy""Mark"201104150.00160065.91160065.9143419.40116646.510.000.000.00160065.9143419.401000000.00138450.0021547.75159997.750.0068.160.00160065.910.000.000.000.000.000.000.000.000.00160065.9143419.400.000.000.000.000.000.005000.000.000.000.000.0043419.400.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.00138450.0021547.75159997.750.0068.160.00160065.910.000.000.000.000.000.000.000.000.00160065.9143419.400.000.000.000.000.000.000.000.000.000.000.0043419.400.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.00 3 | SA17AC00494393SA17.19538IND"ALLEN""JOHN""DR.""1052 CANNON MILL DRIVE""NORTH AUGUSTA"SC298608420P201220110322250.00250.0015"CONTRIBUTION""NORTH AUGUSTA PEDIATRICS""PHYSICIAN" 4 | SB23C00494393SB23.1115ORG"NEW FRONTIER STRATEGY""315 KENTUCKY AVE""ALEXANDRIA"VA22305P2012201103318889.86"POLITICAL STRATEGY CONSULTING/TRAVEL" 5 | -------------------------------------------------------------------------------- /spec/data/730635.fec: -------------------------------------------------------------------------------- 1 | HDRFEC7.0FECfile7.0.1.0(f26)FEC-7273582 2 | F1MAC00454660Oklahoma Assoication of Career and Technology Education PAC (OkACTE PAC)4545 N Lincoln BlvdSuite 159Oklahoma CityOK73105NH4OK02089BORENDAVID DHOK0220080825COLETOMHOK0420081020H6OK05160FALLINMARY C.HOK0520080812S8OK00233RICEANDREW MONROESOK0020080924H0OK05114LANKFORDJAMESHOK0520100910200809032008090320100910McGregorPatrick20110607 3 | -------------------------------------------------------------------------------- /spec/data/747058.fec: -------------------------------------------------------------------------------- 1 | HDRFEC8.0FECfile8.0.1.0(f28) 2 | F7NC70003223Los Angeles County Federation of Labor, AFL-CIO2130 James M. Wood Blvd.Los AngelesCA90006LQ3201107012011093014901.35DurazoMaria ElenaTreasurer20111007 3 | F76C70003223F76.4100DMM201107017635.10R2011RunoffSH8CA36097HahnJaniceHCA36 4 | F76C70003223F76.4101TPM201107017266.25R2011RunoffSH8CA36097HahnJaniceHCA36 5 | -------------------------------------------------------------------------------- /spec/data/752356.fec: -------------------------------------------------------------------------------- 1 | HDRFEC8.0FECfile8.0.1.0(f28) 2 | F24NC00504241489-9-9 FUND2776 S ARLINGTON MILL DRIVE #806ARLINGTONVA22206MACKENZIESCOTT B20111112 3 | SEC00504241SE.4174ORGAINSLEY SHEA1295 BANDANA BLVD N #240ST PAULMN55108P20122011111225000.003915.00IOWA CABLE TV BUY 004C00504241SP00003608CAINHERMANP00MACKENZIESCOTT B20111112 4 | SEC00504241SE.4173ORGINFOCISION MANAGEMENT CORP325 SPRINGSIDE DRIVEAKRONOH44333P2012201111123915.003915.00VOTER CONTACT & ID (EST. COST)004C00504241SP00003608CAINHERMANP00MACKENZIESCOTT B20111112 5 | SEC00504241SE.4175ORGINTERMARKETS INC11911 FREEDOM DRIVESUITE 1140RESTONVA20190P2012201111125000.003915.00ONLINE ADS004C00504241SP00003608CAINHERMANP00MACKENZIESCOTT B20111112 6 | -------------------------------------------------------------------------------- /spec/data/753533.fec: -------------------------------------------------------------------------------- 1 | HDRFEC8.0FECfile8.0.1.0(f28) 2 | F3XNC004485633RD AND LONG PACPO BOX 8446ASHEVILLENC28814M112011100120111031BurnsTroy201111207989.485500.0013489.48300.0013189.480.00600.002500.000.002500.000.003000.005500.000.000.000.000.000.000.000.000.000.005500.005500.000.000.00300.00300.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.00300.00300.005500.000.005500.00300.000.00300.00479.88201163020.0063499.8850310.4013189.4820000.0018520.0038520.000.0024500.0063020.000.000.000.000.000.000.000.000.000.0063020.0063020.000.000.0042310.4042310.400.002000.000.000.000.000.000.000.000.000.006000.000.000.000.000.0050310.4050310.4063020.000.0063020.0042310.400.0042310.40 3 | SA11AIC00448563SA11AI.4621INDRatcliffeBrandon301 N Elm St.GreensboroNC27401201110112500.002500.00ContributionPFBMarket Manager 4 | SA11CC00448563SA11C.4618COMDAWG PAC - DEMOCRATS AGAINST WASTE IN GOVERNMENTPO BOX 83142GAITHERSBURGMD20883201110032000.002000.00ContributionC00455360DAWG PAC - DEMOCRATS AGAINST WASTE IN GOVERNMENT 5 | SA11CC00448563SA11C.4616COMKENTUCKY FORWARD PACPO BOX 257FRANKFORTKY40602201110031000.001000.00ContributionC00417717KENTUCKY FORWARD PAC 6 | SB21BC00448563SB21B.4615ORGNGP Software Inc1225 I St NWWashingtonDC2000520111012300.00Database 7 | SD10C00448563SD10.4540ORGNGP Software Inc1225 I St NWWashingtonDC20005compliance and fundraising database software600.000.000.00600.00 8 | -------------------------------------------------------------------------------- /spec/data/764901.fec: -------------------------------------------------------------------------------- 1 | HDRFEC8.0CMDI FEC FILER9.1.1 2 | F9N"C30001655""PAC""Crossroads Grassroots Policy Strategies""1401 New York Avenue NW""Ste. 1200""Washington""DC"20005201201262012020620120206"Every Level""CLQ""Crosby""Caleb""1401 New York Avenue NW, Ste 1200""Washington""DC"20005"Crossroads GPS""CFO"0.002885.86"Crosby""Caleb"20120207 3 | F91"C30001655""S.1""Law""Steven""1401 New York Avenue NW, Ste 1200""Washington""DC"20005"Crossroads GPS""Executive Director" 4 | F93"C30001655""E.1""ORG""Upgrade Films""3299 K Street NW, Ste 200""Washington""DC"20007"P2012"2012013065.51"TV/Media Production (Every Level)"20120206 5 | F93"C30001655""E.2""ORG""Crossroads Media LLC""66 Canal Center Plaza, Ste 55""Alexandria""VA"22314"P2012"201201262820.35"TV/Media Placement (Every Level)"20120206 6 | F94"C30001655""C.""E.1""F93""P80003338""Obama""Barack""H.""P""HI""P2012" 7 | F94"C30001655""C.2""E.2""F93""P80003338""Obama""Barack""H.""P""HI""P2012" 8 | -------------------------------------------------------------------------------- /spec/data/765310.fec: -------------------------------------------------------------------------------- 1 | HDRFEC8.0StatecraftvCraftB4.2.98RunTime: 02/10/2012 03:26:03 PM 2 | F1NC00013128Congressman Waxman Campaign Committee6380 Wilshire Blvd., #1612Los AngelesCA90048Xjane20@pacbell.net20120210PadillaMary Ellen20120210AH6CA24048WaxmanHenryAHCA33DEMLA PAC6380 Wilshire Blvd # 1612Los AngelesCA90048LPSPadillaMary Ellen6380 Wilshire Blvd. Suite 1612Los AngelesCA90048Assistant Treasurer3236554065PadillaMary Ellen6380 Wilshire Blvd. Suite 1612Los AngelesCA90048Treasurer3236554065LeidermanJane6380 Wilshire Blvd. Suite 1612Los AngelesCA90048Assistant Treasurer3236554065CA Bank & Trust550 S Hope StLos AngelesCA90071 3 | -------------------------------------------------------------------------------- /spec/data/771694.fec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwillis/Fech/b5a07597d6ef398266b0f4f82cda424141d213ad/spec/data/771694.fec -------------------------------------------------------------------------------- /spec/data/82094.fec: -------------------------------------------------------------------------------- 1 | "HDR","FEC","5.00","Aristotle International CM4 PM4","Version 4.2.1","^","","" 2 | "F3N","C00320457","Team Emerson for Jo Ann Emerson","P.O. Box 822","","Cape Girardeau","MO","63702 "," ","MO",08,"Q1","G ", ,"","","X","","",20030101,20030331,12558.35,20.00,12538.35,55673.34,0.00,55673.34,185818.68,0.00,0.00,2500.00,140.00,2640.00,418.35,9500.00,0.00,12558.35,0.00,0.00,0.00,0.00,0.00,652.97,13211.32,55673.34,0.00,0.00,0.00,0.00,20.00,0.00,0.00,20.00,12855.00,68548.34,241155.70,13211.32,254367.02,68548.34,185818.68,17233.35,20.00,17213.35,132748.71,0.00,132748.71,,,5815.00,418.35,11000.00,0.00,17233.35,0.00,0.00,0.00,0.00,0.00,1170.26,18403.61,132748.71,0.00,0.00,0.00,0.00,20.00,0.00,0.00,20.00,12855.00,145623.71,"David S. Limbaugh",20030415 3 | "TEXT","F3N","","" 4 | "SA11C","C00320457","PAC","HOLCIM, Inc. PAC","6211 Ann Arbor Road","","Dundee","MI","48131 ","P ","","","",1500.00,20030331,1500.00,"18K","Receipt","","","","","",,"","","","","","","","","","0414200339C29117","","","","" 5 | "SA11C","C00320457","PAC","PASS PAC - Professional Airways","Systems Specialists","1150 - 17th Street, NW ","Washington","DC","20036 ","P ","","","Administrative Director",1500.00,20030331,1500.00,"18K","Receipt","C00286807","","","","",,"","","","","","","","","","0409200320C29109","","","","" 6 | "SA11C","C00320457","PAC","NRLCA Political Action Committee","National Rural Letter Carriers As","1630 Duke Street, 4th Floor ","Alexandria","VA","223143465","P ","","","",1500.00,20030331,1500.00,"18K","Receipt","","","","","",,"","","","","","","","","","0409200320C29110","","","","" 7 | "SA11C","C00320457","PAC","AFLAC Incorporated PAC","1932 Wynnton Road","","Columbus","GA","31999 ","P ","","","",1500.00,20030331,1500.00,"18K","Receipt","","","","","",,"","","","","","","","","","0409200320C29107","","","","" 8 | "SA11A1","C00320457","IND","Franco^Alan","809 Jefferson Highway","","New Orleans","LA","70121 ","P ","","Magnolia Marketing Company","Vice President",2000.00,20030331,2000.00,"15","Receipt","","","","","",,"","","","","","","","","","0414200339C29116","","","","" 9 | "SA11C","C00320457","PAC","Boeing PAC","1200 Wilson Boulevard","","Arlington","VA","22209 ","P ","","","PAC Manager",1500.00,20030331,1500.00,"18K","Receipt","","","","","",,"","","","","","","","","","0414200339C29118","","","","" 10 | "SA11B","C00320457","PTY","NRCC","Natl Republican Congressional Com","320 First Street, S.E. ","Washington","DC","20003 ","P ","","","",201.32,20030107,201.32,"15Z","In-Kind","","","","","",,"","","","","","","","","","0415200332C29119","","","","" 11 | "SA11B","C00320457","PTY","NRCC","Natl Republican Congressional Com","320 First Street, S.E. ","Washington","DC","20003 ","P ","","","",219.71,20030128,18.39,"15Z","In-Kind","","","","","",,"","","","","","","","","","0415200332C29120","","","","" 12 | "SA11B","C00320457","PTY","NRCC","Natl Republican Congressional Com","320 First Street, S.E. ","Washington","DC","20003 ","P ","","","",418.35,20030320,198.64,"15Z","In-Kind","","","","","",,"","","","","","","","","","0415200332C29121","","","","" 13 | "SA11A1","C00320457","IND","Pinckley^Guy","402 Palo Verde","","Malden","MO","63863 ","P ","","","Retired",500.00,20030206,500.00,"15","Receipt","","","","","",,"","","","","","","","","","0409200320C29104","","","","" 14 | "SA11C","C00320457","PAC","Pork PAC","National Pork Producers","122 C Street, N.W. ","Washington","DC","20001 ","P ","","","",1000.00,20030305,1000.00,"18K","Receipt","","","","","",,"","","","","","","","","","0409200320C29105","","","","" 15 | "SA11C","C00320457","PAC","ADM PAC","PO Box 1470","","Decatur","IL","62525 ","P ","","","Attorney",1000.00,20030331,1000.00,"18K","Receipt","","","","","",,"","","","","","","","","","0409200320C29108","","","","" 16 | "SA15","C00320457","","First National Bank","2027 Broadway","","Cape Girardeau","MO","63701 ","P ","","","",726.99,20030131,209.70,"17R","Other Receipt","","","","","","","","","","","","","","","","0414200339C29113","","","" 17 | "SA15","C00320457","","First National Bank","2027 Broadway","","Cape Girardeau","MO","63701 ","P ","","","",910.53,20030228,183.54,"17R","Other Receipt","","","","","","","","","","","","","","","","0414200339C29114","","","" 18 | "SA15","C00320457","","First National Bank","2027 Broadway","","Cape Girardeau","MO","63701 ","P ","","","",1085.96,20030331,175.43,"17R","Other Receipt","","","","","","","","","","","","","","","","0414200339C29115","","","" 19 | "SA15","C00320457","","American Economy Insurance","First National Insurance Agency","PO Box 589 ","Sikeston","MO","63801 ","P ","","","",49.73,20030204,49.73,"17R","Other Receipt","","","","","","","","","","","","","","","","0409200320C29103","","","" 20 | "SA15","C00320457","","Southwestern Bell Communications","PO Box 940012","","Dallas","TX","753940012","P ","","","",34.57,20030204,34.57,"17R","Other Receipt","","","","","","","","","","","","","","","","0411200316C29111","","","" 21 | "SB17","C00320457","","AAA Mini Storage","1815 Cape La Croix Road","","Cape Girardeau","MO","63701 ","","STORAGE EXPENSE","","",20030207,170.00,"C00320457","","","","",,"","","","","","","","STORAGE EXPENSE","","0409200320E7524","","","","","" 22 | "SB17","C00320457","","AAA Mini Storage","1815 Cape La Croix Road","","Cape Girardeau","MO","63701 ","","STORAGE EXPENSE","","",20030225,85.00,"C00320457","","","","",,"","","","","","","","STORAGE EXPENSE","","0411200316E7554","","","","","" 23 | "SB17","C00320457","","Ameren Union Electric","PO Box 66529","","Saint Louis","MO","63166 ","","UTILITIES EXPENSE","","",20030116,185.00,"C00320457","","","","",,"","","","","","","","UTILITIES EXPENSE","","0130200329E7466","","","","","" 24 | "SB17","C00320457","","Ameren Union Electric","PO Box 66529","","Saint Louis","MO","63166 ","","UTILITIES EXPENSE","","",20030203,262.45,"C00320457","","","","",,"","","","","","","","UTILITIES EXPENSE","","0409200320E7513","","","","","" 25 | "SB17","C00320457","","Ameren Union Electric","PO Box 66529","","Saint Louis","MO","63166 ","","UTILITIES EXPENSE","","",20030305,260.50,"C00320457","","","","",,"","","","","","","","UTILITIES EXPENSE","","0411200316E7566","","","","","" 26 | "SB17","C00320457","","American Express","Suite 0001","","Chicago","IL","606790001","","MISC. MEALS & TRAVEL AND SEE BELOW","","",20030113,7133.50,"C00320457","","","","",,"","","","","","","","MISC. MEALS & TRAVEL AND SEE BELOW","","0414200339E7597","","","","","" 27 | "SB17","C00320457","","American Airlines","PO Box 619612","MD 2400 ","Dallas","TX","752619612","","TRAVEL EXPENSE","","",20030113,306.00,"C00320457","","","","",,"","","","","","","X","MEMO: TRAVEL EXPENSE","","0414200339E7602","","","","","" 28 | "SB17","C00320457","","American Airlines","PO Box 619612","MD 2400 ","Dallas","TX","752619612","","TRAVEL EXPENSE","","",20030113,250.00,"C00320457","","","","",,"","","","","","","X","MEMO: TRAVEL EXPENSE","","0414200339E7598","","","","","" 29 | "SB17","C00320457","","American Airlines","PO Box 619612","MD 2400 ","Dallas","TX","752619612","","TRAVEL EXPENSE","","",20030113,228.00,"C00320457","","","","",,"","","","","","","X","MEMO: TRAVEL EXPENSE","","0414200339E7603","","","","","" 30 | "SB17","C00320457","","Coach","7100 S. Croatan Hwy #219","","Nags Head","NC","27959 ","","POLITICAL GIFTS","","",20030113,252.41,"C00320457","","","","",,"","","","","","","X","MEMO: POLITICAL GIFTS","","0414200339E7604","","","","","" 31 | "SB17","C00320457","","Emerils Restaurant","800 Tchoupitoulas","","New Orleans","LA","70130 ","","POLITICAL MEAL","","",20030113,2449.98,"C00320457","","","","",,"","","","","","","X","MEMO: POLITICAL MEAL","","0414200339E7599","","","","","" 32 | "SB17","C00320457","","Food Giant","1445 Chain Bridge Road","","Mc Lean","VA","22101 ","","POLITICAL MEALS","","",20030113,392.33,"C00320457","","","","",,"","","","","","","X","MEMO: POLITICAL MEALS","","0414200339E7601","","","","","" 33 | "SB17","C00320457","","US Airways","PO Box 5","","Winston Salem","NC","27102 ","","TRAVEL EXPENSE","","",20030113,240.00,"C00320457","","","","",,"","","","","","","X","MEMO: TRAVEL EXPENSE","","0414200339E7606","","","","","" 34 | "SB17","C00320457","","White House Historical Assoc.","Museum Shop","1450 Pennsylvania Ave., NW ","Washington","DC","20230 ","","POLITICAL GIFTS","","",20030113,971.00,"C00320457","","","","",,"","","","","","","X","MEMO: POLITICAL GIFTS","","0414200339E7605","","","","","" 35 | "SB17","C00320457","","Wyndham Hotels","610 Poydras St.","","New Orleans","LA","70130 ","","POLITICAL LODGING","","",20030113,531.45,"C00320457","","","","",,"","","","","","","X","MEMO: POLITICAL LODGING","","0414200339E7600","","","","","" 36 | "SB17","C00320457","","American Express","Suite 0001","","Chicago","IL","606790001","","MISC. MEALS & TRAVEL UNDER $200","","",20030130,452.37,"C00320457","","","","",,"","","","","","","","MISC. MEALS & TRAVEL UNDER $200","","0409200320E7511","","","","","" 37 | "SB17","C00320457","","American Express","Suite 0001","","Chicago","IL","606790001","","MISC. MEALS & TRAVEL AND SEE BELOW","","",20030207,1394.72,"C00320457","","","","",,"","","","","","","","MISC. MEALS & TRAVEL AND SEE BELOW","","0414200339E7608","","","","","" 38 | "SB17","C00320457","","Colvin Run Tavern","8045 Leesburg Pike","","Vienna","VA","22182 ","","POLITICAL FUNDRAISING","","",20030207,622.89,"C00320457","","","","",,"","","","","","","X","MEMO: POLITICAL FUNDRAISING","","0414200339E7607","","","","","" 39 | "SB17","C00320457","","American Express","Suite 0001","","Chicago","IL","606790001","","MISC. MEALS & TRAVEL AND SEE BELOW","","",20030313,3412.06,"C00320457","","","","",,"","","","","","","","MISC. MEALS & TRAVEL AND SEE BELOW","","0414200339E7616","","","","","" 40 | "SB17","C00320457","","American Airlines","PO Box 619612","MD 2400 ","Dallas","TX","752619612","","TRAVEL EXPENSE","","",20030313,209.00,"C00320457","","","","",,"","","","","","","X","MEMO: TRAVEL EXPENSE","","0414200339E7620","","","","","" 41 | "SB17","C00320457","","Capital City Steakhouse","127 East High St.","","Jefferson City","MO","65101 ","","POLITICAL MEAL","","",20030313,775.00,"C00320457","","","","",,"","","","","","","X","MEMO: POLITICAL MEAL","","0414200339E7619","","","","","" 42 | "SB17","C00320457","","Southwest Airlines","St. Louis Lambert Airport","","Bridgeton","MO","63044 ","","TRAVEL EXPENSE","","",20030313,204.50,"C00320457","","","","",,"","","","","","","X","MEMO: TRAVEL EXPENSE","","0414200339E7618","","","","","" 43 | "SB17","C00320457","","The Greenbrier","300 West Main St.","","White Sulphur Spgs","WV","24986 ","","POLITICAL LODGING","","",20030313,475.42,"C00320457","","","","",,"","","","","","","X","MEMO: POLITICAL LODGING","","0414200339E7617","","","","","" 44 | "SB17","C00320457","","Aristotle Publishing, Inc.","205 Pennsylvania Avenue, S.E.","","Washington","DC","200031164","","SOFTWARE MAINTENANCE","","",20030225,2750.00,"C00320457","","","","",,"","","","","","","","SOFTWARE MAINTENANCE","","0411200316E7558","","","","","" 45 | "SB17","C00320457","","AT&T","PO Box 27-680","","Kansas City","MO","641800680","","TELEPHONE EXPENSE","","",20030116,141.22,"C00320457","","","","",,"","","","","","","","TELEPHONE EXPENSE","","0130200329E7478","","","","","" 46 | "SB17","C00320457","","AT&T","PO Box 27-680","","Kansas City","MO","641800680","","TELEPHONE EXPENSE","","",20030207,208.33,"C00320457","","","","",,"","","","","","","","TELEPHONE EXPENSE","","0409200320E7526","","","","","" 47 | "SB17","C00320457","","AT&T","PO Box 27-680","","Kansas City","MO","641800680","","TELEPHONE EXPENSE","","",20030314,189.46,"C00320457","","","","",,"","","","","","","","TELEPHONE EXPENSE","","0411200316E7575","","","","","" 48 | "SB17","C00320457","","Begley, Janssen, Young and Birk","2103 Themis","","Cape Girardeau","MO","63701 ","","PAYROLL","","",20030102,1742.06,"C00320457","","","","",,"","","","","","","","PAYROLL","","0130200328E7457","","","","","" 49 | "SB17","C00320457","","Begley, Janssen, Young and Birk","2103 Themis","","Cape Girardeau","MO","63701 ","","PAYROLL","","",20030115,972.47,"C00320457","","","","",,"","","","","","","","PAYROLL","","0130200329E7465","","","","","" 50 | "SB17","C00320457","","Begley, Janssen, Young and Birk","2103 Themis","","Cape Girardeau","MO","63701 ","","PROFESSIONAL SERVICES","","",20030116,100.00,"C00320457","","","","",,"","","","","","","","PROFESSIONAL SERVICES","","0130200329E7479","","","","","" 51 | "SB17","C00320457","","Begley, Janssen, Young and Birk","2103 Themis","","Cape Girardeau","MO","63701 ","","PAYROLL","","",20030130,972.47,"C00320457","","","","",,"","","","","","","","PAYROLL","","0409200320E7509","","","","","" 52 | "SB17","C00320457","","Begley, Janssen, Young and Birk","2103 Themis","","Cape Girardeau","MO","63701 ","","PAYROLL","","",20030213,971.79,"C00320457","","","","",,"","","","","","","","PAYROLL","","0409200320E7539","","","","","" 53 | "SB17","C00320457","","Begley, Janssen, Young and Birk","2103 Themis","","Cape Girardeau","MO","63701 ","","PROFESSIONAL SERVICES","","",20030225,275.00,"C00320457","","","","",,"","","","","","","","PROFESSIONAL SERVICES","","0411200316E7559","","","","","" 54 | "SB17","C00320457","","Begley, Janssen, Young and Birk","2103 Themis","","Cape Girardeau","MO","63701 ","","PAYROLL","","",20030228,971.79,"C00320457","","","","",,"","","","","","","","PAYROLL","","0411200316E7565","","","","","" 55 | "SB17","C00320457","","Begley, Janssen, Young and Birk","2103 Themis","","Cape Girardeau","MO","63701 ","","PAYROLL","","",20030315,611.04,"C00320457","","","","",,"","","","","","","","PAYROLL","","0411200316E7581","","","","","" 56 | "SB17","C00320457","","Begley, Janssen, Young and Birk","2103 Themis","","Cape Girardeau","MO","63701 ","","PAYROLL","","",20030331,611.04,"C00320457","","","","",,"","","","","","","","PAYROLL","","0411200316E7591","","","","","" 57 | "SB17","C00320457","IND","Bernhardt^Iris","7 King Drive","","Rolla","MO","65401 ","","MISCELLANEOUS EXPENSE","","",20030211,25.00,"C00320457","","","","",,"","","","","","","","MISCELLANEOUS EXPENSE","","0409200320E7537","","","","","" 58 | "SB17","C00320457","IND","Bernhardt^Iris","7 King Drive","","Rolla","MO","65401 ","","MISC. MEALS & TRAVEL","","",20030225,200.89,"C00320457","","","","",,"","","","","","","","MISC. MEALS & TRAVEL","","0411200316E7553","","","","","" 59 | "SB17","C00320457","","Concord","430 Broadway","","Cape Girardeau","MO","63701 ","","CHRISTMAS CARD EXPENSE","","",20030116,2003.86,"C00320457","","","","",,"","","","","","","","CHRISTMAS CARD EXPENSE","","0130200329E7470","","","","","" 60 | "SB17","C00320457","","Concord","430 Broadway","","Cape Girardeau","MO","63701 ","","PRINTING EXPENSE","","",20030207,53.10,"C00320457","","","","",,"","","","","","","","PRINTING EXPENSE","","0409200320E7518","","","","","" 61 | "SB17","C00320457","","Congressional Institute","401 Wythe St.","Suite 103 ","Alexandria","VA","22314 ","","REGISTRATION FEE","","",20030114,1214.00,"C00320457","","","","",,"","","","","","","","REGISTRATION FEE","","0130200329E7500","","","","","" 62 | "SB17","C00320457","","Congressional Institute","401 Wythe St.","Suite 103 ","Alexandria","VA","22314 ","","REGISTRATION FEE","","",20030204,98.00,"C00320457","","","","",,"","","","","","","","REGISTRATION FEE","","0409200320E7515","","","","","" 63 | "SB17","C00320457","","Ekern & Company","1212 New York Avenue, NW","Ste. 350 ","Washington","DC","20007 ","","FUNDRAISING EXPENSE","","",20030116,3007.52,"C00320457","","","","",,"","","","","","","","FUNDRAISING EXPENSE","","0130200329E7473","","","","","" 64 | "SB17","C00320457","","Ekern & Company","1212 New York Avenue, NW","Ste. 350 ","Washington","DC","20007 ","","FUNDRAISING EXPENSE","","",20030225,3005.75,"C00320457","","","","",,"","","","","","","","FUNDRAISING EXPENSE","","0411200316E7556","","","","","" 65 | "SB17","C00320457","","Element 74","2845 Independence","","Cape Girardeau","MO","63701 ","","WEBSITE HOST & COMPUTER EXPENSE","","",20030207,275.00,"C00320457","","","","",,"","","","","","","","WEBSITE HOST & COMPUTER EXPENSE","","0409200320E7520","","","","","" 66 | "SB17","C00320457","","Element 74","2845 Independence","","Cape Girardeau","MO","63701 ","","COMPUTER EXPENSE","","",20030225,3343.58,"C00320457","","","","",,"","","","","","","","COMPUTER EXPENSE","","0411200316E7557","","","","","" 67 | "SB17","C00320457","","Element 74","2845 Independence","","Cape Girardeau","MO","63701 ","","COMPUTER & LABOR EXPENSE","","",20030314,999.11,"C00320457","","","","",,"","","","","","","","COMPUTER & LABOR EXPENSE","","0414200339E7621","","","","","" 68 | "SB17","C00320457","CAN","Jo Ann Emerson","1637 Themis","","Cape Girardeau","MO","63701 ","","MISC. MEALS & TRAVEL UNDER $200","","",20030314,341.82,"C00320457","","","","",,"","","","","","","","MISC. MEALS & TRAVEL UNDER $200","","0411200316E7582","","","","","" 69 | "SB17","C00320457","CAN","Jo Ann Emerson","1637 Themis","","Cape Girardeau","MO","63701 ","","MISC. MEALS & TRAVEL UNDER $200","","",20030321,351.51,"C00320457","","","","",,"","","","","","","","MISC. MEALS & TRAVEL UNDER $200","","0414200339E7623","","","","","" 70 | "SB17","C00320457","","Enterprise Rent-A-Car","PO Box 16030","","St. Louis","MO","631050730","","CAR RENTAL","","",20030116,314.96,"C00320457","","","","",,"","","","","","","","CAR RENTAL","","0130200329E7477","","","","","" 71 | "SB17","C00320457","","Enterprise Rent-A-Car","PO Box 16030","","St. Louis","MO","631050730","","CAR RENTAL","","",20030207,218.49,"C00320457","","","","",,"","","","","","","","CAR RENTAL","","0409200320E7519","","","","","" 72 | "SB17","C00320457","","Enterprise Rent-A-Car","PO Box 16030","","St. Louis","MO","631050730","","CAR RENTAL","","",20030314,1029.93,"C00320457","","","","",,"","","","","","","","CAR RENTAL","","0411200316E7574","","","","","" 73 | "SB17","C00320457","","Federal Express","PO Box 1140","","Memphis","TN","381011140","","SHIPPING EXPENSE","","",20030116,542.43,"C00320457","","","","",,"","","","","","","","SHIPPING EXPENSE","","0130200329E7475","","","","","" 74 | "SB17","C00320457","","Federal Express","PO Box 1140","","Memphis","TN","381011140","","SHIPPING EXPENSE","","",20030225,200.20,"C00320457","","","","",,"","","","","","","","SHIPPING EXPENSE","","0411200316E7560","","","","","" 75 | "SB17","C00320457","","Federal Express","PO Box 1140","","Memphis","TN","381011140","","SHIPPING EXPENSE","","",20030313,113.91,"C00320457","","","","",,"","","","","","","","SHIPPING EXPENSE","","0411200316E7571","","","","","" 76 | "SB17","C00320457","","First National Bank","2027 Broadway","","Cape Girardeau","MO","63701 ","","BANK CHARGE","","",20030101,39.50,"C00320457","","","","",,"","","","","","","","BANK CHARGE","","0130200329E7501","","","","","" 77 | "SB17","C00320457","","First National Bank","2027 Broadway","","Cape Girardeau","MO","63701 ","","FEDERAL TAX DEPOSIT","","",20030107,1467.85,"C00320457","","","","",,"","","","","","","","FEDERAL TAX DEPOSIT","","0130200328E7460","","","","","" 78 | "SB17","C00320457","","First National Bank","2027 Broadway","","Cape Girardeau","MO","63701 ","","BANK CHARGE","","",20030201,39.50,"C00320457","","","","",,"","","","","","","","BANK CHARGE","","0409200320E7514","","","","","" 79 | "SB17","C00320457","","First National Bank","2027 Broadway","","Cape Girardeau","MO","63701 ","","FEDERAL TAX DEPOSIT","","",20030204,662.30,"C00320457","","","","",,"","","","","","","","FEDERAL TAX DEPOSIT","","0409200320E7516","","","","","" 80 | "SB17","C00320457","","First National Bank","2027 Broadway","","Cape Girardeau","MO","63701 ","","RETURN CHECK CHARGE","","",20030218,2.00,"C00320457","","","","",,"","","","","","","","RETURN CHECK CHARGE","","0414200339E7611","","","","","" 81 | "SB17","C00320457","","First National Bank","2027 Broadway","","Cape Girardeau","MO","63701 ","","BANK SERVICE CHARGE","","",20030227,7.91,"C00320457","","","","",,"","","","","","","","BANK SERVICE CHARGE","","0414200339E7615","","","","","" 82 | "SB17","C00320457","","First National Bank","2027 Broadway","","Cape Girardeau","MO","63701 ","","FEDERAL TAX DEPOSIT","","",20030305,661.66,"C00320457","","","","",,"","","","","","","","FEDERAL TAX DEPOSIT","","0411200316E7567","","","","","" 83 | "SB17","C00320457","","First National Bank","2027 Broadway","","Cape Girardeau","MO","63701 ","","BANK CHARGE","","",20030305,39.50,"C00320457","","","","",,"","","","","","","","BANK CHARGE","","0414200339E7622","","","","","" 84 | "SB17","C00320457","","First National Bank","2027 Broadway","","Cape Girardeau","MO","63701 ","","FEDERAL TAX DEPOSIT","","",20030317,541.00,"C00320457","","","","",,"","","","","","","","FEDERAL TAX DEPOSIT","","0411200316E7583","","","","","" 85 | "SB17","C00320457","","Knaup Floral","838 William Street","","Cape Girardeau","MO","63701 ","","FUNERAL FLOWERS","","",20030116,37.35,"C00320457","","","","",,"","","","","","","","FUNERAL FLOWERS","","0130200329E7476","","","","","" 86 | "SB17","C00320457","","Knaup Floral","838 William Street","","Cape Girardeau","MO","63701 ","","POLITICAL FLOWERS","","",20030207,42.30,"C00320457","","","","",,"","","","","","","","POLITICAL FLOWERS","","0409200320E7527","","","","","" 87 | "SB17","C00320457","","Knaup Floral","838 William Street","","Cape Girardeau","MO","63701 ","","POLITICAL/FUNERAL FLOWERS","","",20030314,81.71,"C00320457","","","","",,"","","","","","","","POLITICAL/FUNERAL FLOWERS","","0411200316E7578","","","","","" 88 | "SB17","C00320457","","KREI","PO Box 461","","Farmington","MO","63640 ","","POLITICAL ADVERTISING","","",20030116,200.00,"C00320457","","","","",,"","","","","","","","POLITICAL ADVERTISING","","0130200329E7471","","","","","" 89 | "SB17","C00320457","","KTJJ","PO Box 461","","Farmington","MO","63640 ","","POLITICAL ADVERTISING","","",20030116,250.00,"C00320457","","","","",,"","","","","","","","POLITICAL ADVERTISING","","0130200329E7472","","","","","" 90 | "SB17","C00320457","PTY","Missouri Association of Republicans","c/o Pat & Tom Lehman","2903 SW Scherer Rd. ","Lees Summit","MO","640821304","","REGISTRATION/POLITICAL MEALS","","",20030117,282.00,"C00320457","","","","",,"","","","","","","","REGISTRATION/POLITICAL MEALS","","0130200329E7503","","","","","" 91 | "SB17","C00320457","PTY","Missouri Association of Republicans","c/o Pat & Tom Lehman","2903 SW Scherer Rd. ","Lees Summit","MO","640821304","","REGISTRATION/POLITICAL MEALS","","",20030214,92.00,"C00320457","","","","",,"","","","","","","","REGISTRATION/POLITICAL MEALS","","0414200339E7610","","","","","" 92 | "SB17","C00320457","PTY","Missouri Association of Republicans","c/o Pat & Tom Lehman","2903 SW Scherer Rd. ","Lees Summit","MO","640821304","","REGISTRATION/POLITICAL MEALS","","",20030214,107.00,"C00320457","","","","",,"","","","","","","","REGISTRATION/POLITICAL MEALS","","0414200339E7609","","","","","" 93 | "SB17","C00320457","","Mastercard","PO Box 15098","","Wilmington","DE","198865098","","MISC. MEALS & TRAVEL","","",20030130,124.46,"C00320457","","","","",,"","","","","","","","MISC. MEALS & TRAVEL","","0409200320E7512","","","","","" 94 | "SB17","C00320457","","Mastercard","PO Box 15098","","Wilmington","DE","198865098","","POLITICAL MEALS AND SEE BELOW","","",20030219,735.82,"C00320457","","","","",,"","","","","","","","POLITICAL MEALS AND SEE BELOW","","0414200339E7613","","","","","" 95 | "SB17","C00320457","","Pizzeria Paradiso","3282 M Street, NW","","Washington","DC","20007 ","","POLITICAL MEAL","","",20030219,685.82,"C00320457","","","","",,"","","","","","","X","MEMO: POLITICAL MEAL","","0414200339E7614","","","","","" 96 | "SB17","C00320457","","Mastercard","PO Box 15098","","Wilmington","DE","198865098","","MISC. MEALS & TRAVEL","","",20030319,104.65,"C00320457","","","","",,"","","","","","","","MISC. MEALS & TRAVEL","","0411200316E7588","","","","","" 97 | "SB17","C00320457","","Mastercard","PO Box 15098","","Wilmington","DE","198865098","","MISC. TRAVEL EXPENSE","","",20030320,127.58,"C00320457","","","","",,"","","","","","","","MISC. TRAVEL EXPENSE","","0411200316E7589","","","","","" 98 | "SB17","C00320457","","Mail Boxes, Etc.","209 S. Broadview","","Cape Girardeau","MO","63701 ","","SHIPPING EXPENSE","","",20030116,134.11,"C00320457","","","","",,"","","","","","","","SHIPPING EXPENSE","","0130200329E7468","","","","","" 99 | "SB17","C00320457","","McClanahan Real Estate Co.","PO Box 1115","","Cape Girardeau","MO","637021115","","JANUARY RENT","","",20030103,500.00,"C00320457","","","","",,"","","","","","","","JANUARY RENT","","0130200328E7458","","","","","" 100 | "SB17","C00320457","","MO Department of Revenue","PO Box 999","","Jefferson City","MO","651080999","","EMPLOYERS WITHHOLDING","","",20030107,388.00,"C00320457","","","","",,"","","","","","","","EMPLOYERS WITHHOLDING","","0130200328E7459","","","","","" 101 | "SB17","C00320457","","MO Department of Revenue","PO Box 999","","Jefferson City","MO","651080999","","EMPLOYERS WITHHOLDING","","",20030317,222.00,"C00320457","","","","",,"","","","","","","","EMPLOYERS WITHHOLDING","","0411200316E7584","","","","","" 102 | "SB17","C00320457","PTY","NRCC","Natl Republican Congressional Com","320 First Street, S.E. ","Washington","DC","20003 ","","SATELLITE FEED","","",20030107,201.32,"C00320457","","","","",,"","","","","","","","IN KIND: SATELLITE FEED","","0415200332C29119IK","","","","","" 103 | "SB17","C00320457","PTY","NRCC","Natl Republican Congressional Com","320 First Street, S.E. ","Washington","DC","20003 ","","SATELLITE FEED","","",20030128,18.39,"C00320457","","","","",,"","","","","","","","IN KIND: SATELLITE FEED","","0415200332C29120IK","","","","","" 104 | "SB17","C00320457","PTY","NRCC","Natl Republican Congressional Com","320 First Street, S.E. ","Washington","DC","20003 ","","MEDIA PRODUCTION","","",20030314,44.94,"C00320457","","","","",,"","","","","","","","MEDIA PRODUCTION","","0411200316E7576","","","","","" 105 | "SB17","C00320457","PTY","NRCC","Natl Republican Congressional Com","320 First Street, S.E. ","Washington","DC","20003 ","","SATELLITE FEED","","",20030320,198.64,"C00320457","","","","",,"","","","","","","","IN KIND: SATELLITE FEED","","0415200332C29121IK","","","","","" 106 | "SB17","C00320457","","Postmaster","320 N. Frederick","","Cape Girardeau","MO","63701 ","","POSTAGE","","",20030108,74.00,"C00320457","","","","",,"","","","","","","","POSTAGE","","0130200328E7461","","","","","" 107 | "SB17","C00320457","","Postmaster","320 N. Frederick","","Cape Girardeau","MO","63701 ","","PO BOX RENTAL FEE","","",20030114,44.00,"C00320457","","","","",,"","","","","","","","PO BOX RENTAL FEE","","0130200329E7464","","","","","" 108 | "SB17","C00320457","","Postmaster","320 N. Frederick","","Cape Girardeau","MO","63701 ","","POSTAGE","","",20030207,111.00,"C00320457","","","","",,"","","","","","","","POSTAGE","","0409200320E7534","","","","","" 109 | "SB17","C00320457","","Rental Land","1922 Independence","","Cape Girardeau","MO","63701 ","","EQUIPMENT RENTAL","","",20030207,41.34,"C00320457","","","","",,"","","","","","","","EQUIPMENT RENTAL","","0409200320E7522","","","","","" 110 | "SB17","C00320457","","Rust Investment Properties","2502 Tanner Drive","","Cape Girardeau","MO","637035700","","FEBRUARY RENT","","",20030205,500.00,"C00320457","","","","",,"","","","","","","","FEBRUARY RENT","","0409200320E7517","","","","","" 111 | "SB17","C00320457","","Rust Investment Properties","2502 Tanner Drive","","Cape Girardeau","MO","637035700","","MARCH RENT","","",20030225,500.00,"C00320457","","","","",,"","","","","","","","MARCH RENT","","0411200316E7551","","","","","" 112 | "SB17","C00320457","","Rust Investment Properties","2502 Tanner Drive","","Cape Girardeau","MO","637035700","","APRIL RENT","","",20030313,500.00,"C00320457","","","","",,"","","","","","","","APRIL RENT","","0411200316E7570","","","","","" 113 | "SB17","C00320457","","Sams Club","Siemers Drive","","Cape Girardeau","MO","63701 ","","OFFICE SUPPLIES","","",20030124,47.90,"C00320457","","","","",,"","","","","","","","OFFICE SUPPLIES","","0130200328E7462","","","","","" 114 | "SB17","C00320457","","Sams Club","Siemers Drive","","Cape Girardeau","MO","63701 ","","MEMBERSHIP RENEWAL","","",20030317,30.00,"C00320457","","","","",,"","","","","","","","MEMBERSHIP RENEWAL","","0411200316E7585","","","","","" 115 | "SB17","C00320457","","Southwestern Bell Communications","PO Box 940012","","Dallas","TX","753940012","","TELEPHONE EXPENSE","","",20030207,116.80,"C00320457","","","","",,"","","","","","","","TELEPHONE EXPENSE","","0409200320E7532","","","","","" 116 | "SB17","C00320457","","Southwestern Bell Communications","PO Box 940012","","Dallas","TX","753940012","","TELEPHONE EXPENSE","","",20030314,217.70,"C00320457","","","","",,"","","","","","","","TELEPHONE EXPENSE","","0411200316E7572","","","","","" 117 | "SB17","C00320457","","SBC","32255 Northwestern Highway","Suite 143 ","Farmington","MI","483341573","","PAGER EXPENSE","","",20030207,45.85,"C00320457","","","","",,"","","","","","","","PAGER EXPENSE","","0409200320E7523","","","","","" 118 | "SB17","C00320457","","SBC","32255 Northwestern Highway","Suite 143 ","Farmington","MI","483341573","","PAGER EXPENSE","","",20030225,45.85,"C00320457","","","","",,"","","","","","","","PAGER EXPENSE","","0411200316E7552","","","","","" 119 | "SB17","C00320457","IND","Smith^Lloyd","1204 Sikes","","Sikeston","MO","63801 ","","MISC. MEALS & TRAVEL","","",20030312,243.32,"C00320457","","","","",,"","","","","","","","MISC. MEALS & TRAVEL","","0411200316E7569","","","","","" 120 | "SB17","C00320457","","Staples","Dept. 82","PO Box 30292 ","Salt Lake City","UT","841030292","","OFFICE SUPPLIES","","",20030116,141.05,"C00320457","","","","",,"","","","","","","","OFFICE SUPPLIES","","0130200329E7480","","","","","" 121 | "SB17","C00320457","","Staples","Dept. 82","PO Box 30292 ","Salt Lake City","UT","841030292","","OFFICE SUPPLIES","","",20030314,9.74,"C00320457","","","","",,"","","","","","","","OFFICE SUPPLIES","","0411200316E7573","","","","","" 122 | "SB17","C00320457","IND","Stoker^April","2613 Perryville Road","Apt. 14 ","Cape Girardeau","MO","63701 ","","MISC. MEALS & TRAVEL","","",20030130,94.14,"C00320457","","","","",,"","","","","","","","MISC. MEALS & TRAVEL","","0409200320E7510","","","","","" 123 | "SB17","C00320457","IND","Stoker^April","2613 Perryville Road","Apt. 14 ","Cape Girardeau","MO","63701 ","","MISC. MEALS & TRAVEL","","",20030211,107.24,"C00320457","","","","",,"","","","","","","","MISC. MEALS & TRAVEL","","0409200320E7536","","","","","" 124 | "SB17","C00320457","IND","Stoker^April","2613 Perryville Road","Apt. 14 ","Cape Girardeau","MO","63701 ","","MISC. MEALS & TRAVEL","","",20030307,75.81,"C00320457","","","","",,"","","","","","","","MISC. MEALS & TRAVEL","","0411200316E7568","","","","","" 125 | "SB17","C00320457","","The National Theatre","1321 Pennsylvania Avenue, NW","","Washington","DC","20004 ","","FUNDRAISING EXPENSE","","",20030225,1375.00,"C00320457","","","","",,"","","","","","","","FUNDRAISING EXPENSE","","0411200316E7555","","","","","" 126 | "SB17","C00320457","","The Royan NOrleans","300 Broadway","","Cape Girardeau","MO","63701 ","","POLITICAL MEAL","","",20030116,1305.57,"C00320457","","","","",,"","","","","","","","POLITICAL MEAL","","0130200329E7502","","","","","" 127 | "SB17","C00320457","","Verizon Wireless","PO Box 6170","","Carol Stream","IL","60197 ","","TELEPHONE EXPENSE","","",20030116,69.64,"C00320457","","","","",,"","","","","","","","TELEPHONE EXPENSE","","0130200329E7469","","","","","" 128 | "SB17","C00320457","","Verizon Wireless","PO Box 6170","","Carol Stream","IL","60197 ","","TELEPHONE EXPENSE","","",20030227,153.12,"C00320457","","","","",,"","","","","","","","TELEPHONE EXPENSE","","0411200316E7562","","","","","" 129 | "SB17","C00320457","","Verizon Wireless","PO Box 6170","","Carol Stream","IL","60197 ","","TELEPHONE EXPENSE","","",20030314,71.04,"C00320457","","","","",,"","","","","","","","TELEPHONE EXPENSE","","0411200316E7580","","","","","" 130 | "SB21","C00320457","","American Cancer Society","937 Broadway, Suite 2","","Cape Girardeau","MO","63701 ","","SPONSORSHIP","P ","",20030317,500.00,"C00320457","","","","",,"","","","","","","","","","0411200316E7586","","","","","" 131 | "SB21","C00320457","PTY","Bob Beauprez for Congress","14142 Denver W. Pkwy","Suite 270 ","Golden","CO","80401 ","","POLITICAL DONATION","P ","",20030219,1000.00,"C00320457","","","","",,"","","","","","","","","","0411200316E7540","","","","","" 132 | "SB21","C00320457","PTY","Missourians for Matt Blunt","147 N. Meramec","Suite 100 ","Saint Louis","MO","63105 ","","POLITICAL DONATION","P ","",20030331,1175.00,"C00320457","","","","",,"","","","","","","","","","0411200316E7592","","","","","" 133 | "SB21","C00320457","PTY","Brown-Waite for Congress","204 Ponce De Leon Boulevard","","Brooksville","FL","34601 ","","POLITICAL DONATION","P ","",20030219,1000.00,"C00320457","","","","",,"","","","","","","","","","0411200316E7541","","","","","" 134 | "SB21","C00320457","PTY","Burns for Congress","121 N. Main St. #2","","Sylvania","GA","30467 ","","POLITICAL DONATION","P ","",20030219,1000.00,"C00320457","","","","",,"","","","","","","","","","0411200316E7542","","","","","" 135 | "SB21","C00320457","PTY","Cape Girardeau County Republican Women","c/o Mrs. Carolyn King","2531 Jonquil Lane ","Cape Girardeau","MO","63701 ","","TICKETS","P ","",20030228,90.00,"C00320457","","","","",,"","","","","","","","","","0411200316E7564","","","","","" 136 | "SB21","C00320457","PTY","Cape Girardeau County Republican Women","c/o Mrs. Carolyn King","2531 Jonquil Lane ","Cape Girardeau","MO","63701 ","","POLITICAL DONATION","P ","",20030207,500.00,"C00320457","","","","",,"","","","","","","","","","0409200320E7535","","","","","" 137 | "SB21","C00320457","PTY","Chris Chocola for Congress, Inc.","PO Box 6728","","South Bend","IN","46660 ","","POLITICAL DONATION","P ","",20030219,1000.00,"C00320457","","","","",,"","","","","","","","","","0411200316E7543","","","","","" 138 | "SB21","C00320457","","Ducks Unlimited","PO Box 387","","Jackson","MO","63755 ","","POLITICAL DONATION","P ","",20030129,250.00,"C00320457","","","","",,"","","","","","","","","","0409200320E7508","","","","","" 139 | "SB21","C00320457","PTY","Jim Gerlach for Congress Committee","911 Wolsh Ayres Way","","Malvern","PA","19355 ","","POLITICAL DONATION","P ","",20030219,1000.00,"C00320457","","","","",,"","","","","","","","","","0411200316E7544","","","","","" 140 | "SB21","C00320457","PTY","Gingrey for Congress","PO Box U","","Marietta","GA","30060 ","","POLITICAL DONATION","P ","",20030219,1000.00,"C00320457","","","","",,"","","","","","","","","","0411200316E7545","","","","","" 141 | "SB21","C00320457","PTY","Pearce for Congress","PO Box 2696","","Hobbs","NM","88241 ","","POLITICAL DONATION","P ","",20030219,1000.00,"C00320457","","","","",,"","","","","","","","","","0411200316E7546","","","","","" 142 | "SB21","C00320457","PTY","Porter for Congress","PO Box 26087","","Las Vegas","NV","89126 ","","POLITICAL DONATION","P ","",20030219,1000.00,"C00320457","","","","",,"","","","","","","","","","0411200316E7547","","","","","" 143 | "SB21","C00320457","PTY","Renzi for Congress","PO Box 219","","Flagstaff","AZ","86002 ","","POLITICAL DONATION","P ","",20030219,1000.00,"C00320457","","","","",,"","","","","","","","","","0411200316E7548","","","","","" 144 | "SB21","C00320457","PTY","Mike Rogers for Congress","126 E. 13th Street","","Anniston","AL","36201 ","","POLITICAL DONATION","P ","",20030219,1000.00,"C00320457","","","","",,"","","","","","","","","","0411200316E7549","","","","","" 145 | -------------------------------------------------------------------------------- /spec/data/862554.fec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwillis/Fech/b5a07597d6ef398266b0f4f82cda424141d213ad/spec/data/862554.fec -------------------------------------------------------------------------------- /spec/data/97405.fec: -------------------------------------------------------------------------------- 1 | HDR,FEC,5.00,"Campaign Central",,,,0, 2 | "F3PN","C00386987","BUSH-CHENEY 04, INC.","P.O. BOX 10648","","ARLINGTON","VA","22210",,X,,"Q3",P2004,20041102,,"20030701","20030930",32679798.37,50049763.70,82729562.07,12288117.89,70441444.18,0.00,370599.43,0.00,83945952.26,13923575.88,0.00,49187571.07,16000.00,767411.80,0.00,49970982.87,0.00,0.00,0.00,0.00,20063.03,0.00,0.00,20063.03,58717.80,50049763.70,11506837.31,310650.00,0.00,0.00,0.00,0.00,0.00,429480.58,0.00,41150.00,470630.58,0.00,12288117.89,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,82843771.04,23000.00,1581711.80,0.00,84448482.84,671000.00,0.00,0.00,0.00,20410.03,0.00,0.00,20410.03,58717.80,85198610.67,13943985.91,310650.00,0.00,0.00,0.00,0.00,0.00,445380.58,0.00,57150.00,502530.58,0.00,14757166.49,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,"DAVID HERNDON",20031014 3 | "SA17A","C00386987","IND","Aaker^Steve^Mr.^","16901 Wild Plum Circle","","Morrison","CO","80465","P2004","","Newmont Mining Corporation","Mining Industry Executive",400.00,20030930,400.00,15,Contribution,,,,,,,,,,,,,,"",,SA17.203318,,,"" 4 | "SA17A","C00386987","IND","Aarnio^Terrance J.^Mr.^","19321 S.E. River Drive Court","","Milwaukee","OR","97267","P2004","","Oregon Iron Works","C. E. O.",2000.00,20030930,2000.00,15,Contribution,,,,,,,,,,,,,,"",,SA17.217363,,,"" 5 | "SA17A","C00386987","IND","Abbassi^Jadan^Dr.^","1618 Main Avenue","","Clifton","NJ","07011","P2004","","Self-Employed","Physician",300.00,20030902,300.00,15,Contribution,,,,,,,,,,,,,,"",,SA17.222415,,,"" 6 | "SA17A","C00386987","IND","Abbasi^Mohammad A.^Mr.^","9707 Broadley Drive","","Sugar Land","TX","77478","P2004","","Aupak Eagle, Inc.","C.E.O.",2000.00,20030930,2000.00,15,Contribution,,,,,,,,,,,,,,"",,SA17.145208,,,"" 7 | "SA17A","C00386987","IND","Abbasi^Seyed H^Mr.^","1021 Adelaine Ave.","","South Pasadena","CA","91030","P2004","","Art & Tech","Contractor",2000.00,20030930,2000.00,15,Contribution,,,,,,,,,,,,,,"",,SA17.300657,,,"" 8 | "SA17A","C00386987","IND","Abbey^Scott G.^Mr.^","22 Merimus Brook Road","","Saddle River","CT","07458","P2004","","U.B.S. Services U.S.A., L.L.C.","Information Requested Per Best Efforts",2000.00,20030930,-2000.00,15,Contribution,,,,,,,,,,,,,X,"Redesignation to Compliance",,SA17.221821,,,"" 9 | "SA17A","C00386987","IND","Abbey^Stephen^Mr.^","7270 Cardinal Lane","","Chagrin Falls","OH","44022","P2004","","Revenue Group","Information Requested Per Best Efforts",2000.00,20030930,2000.00,15,Contribution,,,,,,,,,,,,,,"",,SA17.194269,,,"" 10 | "SA17A","C00386987","IND","Abbott^Charles G.^Mr.^","4218 Rockaway Beach Road N.E.","","Bainbridge Island","WA","98110","P2004","","","Retired",500.00,20030902,500.00,15,Contribution,,,,,,,,,,,,,,"",,SA17.220645,,,"" -------------------------------------------------------------------------------- /spec/default_translations_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | def stub_file(filing_id=723604) 4 | Fech::Filing.any_instance.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', "#{filing_id}.fec")) 5 | end 6 | 7 | def unstub_file 8 | Fech::Filing.any_instance.unstub(:file_path) 9 | end 10 | 11 | describe Fech::DefaultTranslations do 12 | 13 | before do 14 | stub_file 15 | end 16 | 17 | after do 18 | unstub_file 19 | end 20 | 21 | describe ".names" do 22 | 23 | it "should add name translations to default translation set" do 24 | filing = Fech::Filing.new(723604, :translate => :names) 25 | filing.translator.translations.size.should > 0 26 | end 27 | 28 | it "should combine name components into aggregate name fields" do 29 | filing = Fech::Filing.new(723604, :translate => :names) 30 | Fech::Mapped.any_instance.stubs(:contributor_prefix).returns("Mr.") 31 | Fech::Mapped.any_instance.stubs(:contributor_first_name).returns("John") 32 | Fech::Mapped.any_instance.stubs(:contributor_middle_name).returns("Charles") 33 | Fech::Mapped.any_instance.stubs(:contributor_last_name).returns("Smith") 34 | Fech::Mapped.any_instance.stubs(:contributor_suffix).returns("III") 35 | filing.rows_like(/sa/).first.contributor_name.should == "Mr. John Charles Smith III" 36 | end 37 | 38 | it "should split an aggregate name into its component parts" do 39 | stub_file(97405) 40 | filing = Fech::Filing.new(97405, :translate => :names) 41 | filing.filing_version.should == "5.00" 42 | row = filing.rows_like(/sa/).first 43 | row.contributor_prefix.should == "Mr." 44 | row.contributor_first_name.should == "Steve" 45 | row.contributor_middle_name.should == "" 46 | row.contributor_last_name.should == "Aaker" 47 | row.contributor_suffix.should == "" 48 | end 49 | 50 | end 51 | 52 | describe ".dates" do 53 | 54 | before do 55 | @filing = Fech::Filing.new(723604, :translate => :dates) 56 | end 57 | 58 | it "should convert values matching YYYYMMDD to Date objects" do 59 | @filing.rows_like(/sa/).first.contribution_date.should == Date.parse("20110322") 60 | end 61 | 62 | it "should pass all other values through untouched" do 63 | @filing.rows_like(/sa/).first.contributor_zip_code.should == "298608420" 64 | end 65 | 66 | it "should pass nils through untouched" do 67 | @filing.rows_like(/sa/).first.conduit_zip.should be_nil 68 | end 69 | 70 | end 71 | 72 | describe ".combine_components_into_name" do 73 | 74 | before do 75 | @defaults = Fech::DefaultTranslations.new(Fech::Translator.new) 76 | end 77 | 78 | it "should accept :field as either Array or Symbol" do 79 | data = {:row => /^sc$/, :version => /^[6-7]/, :field => :lender_candidate} 80 | expect { @defaults.send(:combine_components_into_name, data) }.to_not raise_error 81 | 82 | data[:field] = [data[:field]] 83 | expect { @defaults.send(:combine_components_into_name, data) }.to_not raise_error 84 | end 85 | 86 | end 87 | 88 | describe ".split_name_into_components" do 89 | 90 | before do 91 | @defaults = Fech::DefaultTranslations.new(Fech::Translator.new) 92 | end 93 | 94 | it "should accept :field as either Array or Symbol" do 95 | data = {:row => /^sc$/, :version => /^[6-7]/, :field => :lender_candidate} 96 | expect { @defaults.send(:split_name_into_components, data) }.to_not raise_error 97 | 98 | data[:field] = [data[:field]] 99 | expect { @defaults.send(:split_name_into_components, data) }.to_not raise_error 100 | end 101 | 102 | end 103 | 104 | end -------------------------------------------------------------------------------- /spec/fech_utils_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe FechUtils do 4 | 5 | describe ".regexify" do 6 | 7 | it "should convert symbols to anchored regular expressions" do 8 | regex = Fech.regexify(:date_coverage_from) 9 | regex.should == /^date_coverage_from$/i 10 | end 11 | 12 | it "should convert strings to unanchored regular expressions" do 13 | regex = Fech.regexify("date_coverage_from") 14 | regex.should == /date_coverage_from/i 15 | end 16 | 17 | it "should produce case-insensitive regular expressions" do 18 | regex = Fech.regexify(:date_coverage_from) 19 | regex.match("Date_coverage_FROM").size.should == 1 20 | end 21 | 22 | it "should return a custom regex if passed a row symbol defined in ROW_TYPES" do 23 | regex = Fech.regexify(:f3p) 24 | regex.should == FechUtils::ROW_TYPES[:f3p] 25 | end 26 | 27 | end 28 | 29 | end -------------------------------------------------------------------------------- /spec/filing_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Fech::Filing do 4 | 5 | before do 6 | @filing = Fech::Filing.new(723604) 7 | @filing.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '723604.fec')) 8 | @filing8 = Fech::Filing.new(748730) 9 | @filing8.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '748730.fec')) 10 | @filing_ie = Fech::Filing.new(752356) 11 | @filing_ie.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '752356.fec')) 12 | @filing_pac = Fech::Filing.new(753533) 13 | @filing_pac.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '753533.fec')) 14 | @filing_ec = Fech::Filing.new(764901) 15 | @filing_ec.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '764901.fec')) 16 | @filing_f1 = Fech::Filing.new(765310) 17 | @filing_f1.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '765310.fec')) 18 | @filing_f1m = Fech::Filing.new(730635) 19 | @filing_f1m.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '730635.fec')) 20 | @filing_f3 = Fech::Filing.new(82094) 21 | @filing_f3.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '82094.fec')) 22 | @filing_f7 = Fech::Filing.new(747058) 23 | @filing_f7.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '747058.fec')) 24 | @filing_f13 = Fech::Filing.new(425925) 25 | @filing_f13.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '425925.fec')) 26 | @filing_special_character = Fech::Filing.new(771694) 27 | @filing_special_character.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '771694.fec')) 28 | @filing_f99 = Fech::Filing.new(862554) 29 | @filing_f99.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '862554.fec')) 30 | @filing_encoding = Fech::Filing.new(1247604) 31 | @filing_encoding.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '1247604.fec')) 32 | end 33 | 34 | describe "#filing_version" do 35 | 36 | it "should return the correct filing version" do 37 | @filing.send(:filing_version).should == "7.0" 38 | @filing8.send(:filing_version).should == "8.0" 39 | @filing_ie.send(:filing_version).should == "8.0" 40 | @filing_pac.send(:filing_version).should == "8.0" 41 | @filing_f3.send(:filing_version).should == "5.00" 42 | @filing_special_character.send(:filing_version).should == "8.0" 43 | end 44 | 45 | it "should parse the file only once" do 46 | @filing.expects(:parse_filing_version).once.returns("7.0") 47 | @filing.send(:filing_version) 48 | @filing.send(:filing_version) 49 | end 50 | 51 | end 52 | 53 | describe ".hash_zip" do 54 | 55 | it "should zip the given keys and values into a hash" do 56 | @filing = Fech::Filing.new(723604) 57 | keys = [:one,:three,:two] 58 | values = [1, 3, 2] 59 | @filing.hash_zip(keys, values).should == {:one => 1, :two => 2, :three => 3} 60 | end 61 | 62 | end 63 | 64 | describe "#summary" do 65 | 66 | it "should return the mapped summary row" do 67 | sum = @filing.summary 68 | sum.should be_a_kind_of(Hash) 69 | sum[:form_type].should == "F3PN" 70 | sum_ie = @filing_ie.summary 71 | sum_ie[:form_type].should == "F24N" 72 | sum_pac = @filing_pac.summary 73 | sum_pac[:form_type].should == "F3XN" 74 | sum_ec = @filing_ec.summary 75 | sum_ec[:form_type].should == 'F9N' 76 | sum_f1 = @filing_f1.summary 77 | sum_f1[:form_type].should == "F1N" 78 | sum_f3 = @filing_f3.summary 79 | sum_f3[:form_type].should == "F3N" 80 | sum_f1m = @filing_f1m.summary 81 | sum_f1m[:form_type].should == "F1MA" 82 | sum_f7 = @filing_f7.summary 83 | sum_f7[:form_type].should == 'F7N' 84 | sum_f13 = @filing_f13.summary 85 | sum_f13[:form_type].should == 'F13N' 86 | sum_filing_special_character = @filing_special_character.summary 87 | sum_filing_special_character[:form_type].should == "F3XN" 88 | expect{@filing_encoding.summary}.to_not raise_error 89 | end 90 | end 91 | 92 | describe "#mappings" do 93 | 94 | it "should create a new Mappings instance with correct version" do 95 | @filing.send(:mappings).version.should == "7.0" 96 | end 97 | 98 | it "should memoize itself" do 99 | mapping = Fech::Mappings.new 100 | Fech::Mappings.expects(:new).once.returns(mapping) 101 | @filing.send(:mappings) 102 | @filing.send(:mappings) 103 | end 104 | 105 | end 106 | 107 | describe 'miscelleanous filings' do 108 | it "should handle invalid encoding" do 109 | expect{@filing_f99.rows_like(/f99/).first}.to_not raise_error 110 | end 111 | end 112 | 113 | describe "#rows_like" do 114 | 115 | it "should return only rows matching the specified regex" do 116 | @filing.rows_like(/^sa/).size.should == 1 117 | @filing.rows_like(/^s/).size.should == 2 118 | @filing.rows_like(/^sc/).size.should == 0 119 | @filing_ie.rows_like(/^se/).size.should == 3 120 | @filing_pac.rows_like(/^sa/).size.should == 3 121 | @filing_pac.rows_like(/^sb/).size.should == 1 122 | @filing_pac.rows_like(/^sd/).size.should == 1 123 | @filing_ec.rows_like(/^f91/).size.should == 1 124 | @filing_f3.rows_like(/^sa/).size.should == 17 125 | @filing_f7.rows_like(/^f76/).size.should == 2 126 | @filing_special_character.rows_like(/^sa/).size.should == 13 127 | end 128 | 129 | it "should return an array if no block is given" do 130 | @filing.rows_like(/^s/).class.should == Array 131 | end 132 | 133 | it "should return empty array if no matches found" do 134 | @filing.rows_like(/^sc/).should == [] 135 | end 136 | 137 | it "should yield hashes of row values if passed a block" do 138 | @filing.rows_like(/^sa/) do |c| 139 | c.should be_a_kind_of(Hash) 140 | end 141 | end 142 | 143 | it "should allow case-insensitive string input" do 144 | @filing.rows_like("Sa17a").size.should be > 0 145 | end 146 | 147 | end 148 | 149 | describe "#parse_row?" do 150 | 151 | before do 152 | f = open(@filing.file_path, 'r') 153 | f.readline 154 | @row = f.readline.split(@filing.delimiter) 155 | f.close 156 | end 157 | 158 | it "should return the mapped row" do 159 | @filing.send(:parse_row?, @row).should be_a_kind_of(Hash) 160 | end 161 | 162 | describe "when :parse_if is specified" do 163 | 164 | it "should return the mapped row if :parse_if matches row type" do 165 | @filing.send(:parse_row?, @row, {:parse_if => /^f3p/}).should be_a_kind_of(Hash) 166 | end 167 | 168 | it "should return false if row was skipped" do 169 | @filing.send(:parse_row?, @row, {:parse_if => /^sa/}).should == false 170 | end 171 | 172 | end 173 | 174 | it "should return the raw row data if :raw is true" do 175 | @filing.send(:parse_row?, @row, {:raw => true}).class.should == Array 176 | end 177 | 178 | end 179 | 180 | describe "#map_for" do 181 | 182 | it "should return the correct map for given row type" do 183 | map = @filing.map_for(/sa/) 184 | map.class.should == Array 185 | map.first.should == :form_type 186 | map_ie = @filing_ie.map_for(/se/) 187 | map_ie[21].should == :calendar_y_t_d_per_election_office 188 | map_pac = @filing_pac.map_for(/f3x/) 189 | map_pac[15].should == :qualified_committee 190 | end 191 | 192 | it "should raise error if no map is found" do 193 | lambda { @filing.map_for(/sz/) }.should raise_error 194 | lambda { @filing_pac.map_for(/sz/) }.should raise_error 195 | end 196 | 197 | end 198 | 199 | describe ".map_for" do 200 | 201 | it "should return the correct map for given row type" do 202 | map = Fech::Filing.map_for(/sa/) 203 | map.class.should == Array 204 | map.first.should == :form_type 205 | end 206 | 207 | it "should raise error if no map is found" do 208 | lambda { Fech::Filing.map_for(/sz/) }.should raise_error 209 | end 210 | 211 | it "should allow choice of version" do 212 | v7 = Fech::Filing.map_for(/sa/, :version => 7.0) 213 | v6 = Fech::Filing.map_for(/sa/, :version => 6.1) 214 | v6.should_not == v7 215 | end 216 | 217 | end 218 | 219 | describe "#translator" do 220 | 221 | describe "when Filing was initialized with built-in translations" do 222 | 223 | before do 224 | @translated_filing = Fech::Filing.new(723604, :translate => [:names]) 225 | @translator = @translated_filing.translator 226 | end 227 | 228 | it "returns the Translator created in Filing's initializer" do 229 | @translated_filing.translator.should == @translator 230 | @translated_filing.translator.translations.size.should > 0 231 | end 232 | 233 | end 234 | 235 | describe "when Filing was not initialized with built-in translation" do 236 | 237 | before do 238 | @untranslated_filing = Fech::Filing.new(723604) 239 | end 240 | 241 | it "creates a new Translator with no default ranslations" do 242 | @untranslated_filing.translator.should_not be_nil 243 | @untranslated_filing.translator.class.should == Fech::Translator 244 | @untranslated_filing.translator.translations.should be_empty 245 | end 246 | 247 | end 248 | 249 | end 250 | 251 | describe "#map" do 252 | 253 | before do 254 | f = open(@filing.file_path, 'r') 255 | f.readline 256 | @f3p_row = f.readline.split(@filing.delimiter) 257 | @sa_row = f.readline.split(@filing.delimiter) 258 | f.close 259 | 260 | f_ie = open(@filing_ie.file_path, 'r') 261 | f_ie.readline 262 | @f24_row = f_ie.readline.split(@filing_ie.delimiter) 263 | @se_row = f_ie.readline.split(@filing_ie.delimiter) 264 | f_ie.close 265 | 266 | f_pac = open(@filing_pac.file_path, 'r') 267 | f_pac.readline 268 | @f3x_row = f_pac.readline.split(@filing_pac.delimiter) 269 | @sa11_row = f_pac.readline.split(@filing_pac.delimiter) 270 | f_pac.close 271 | end 272 | 273 | it "should map the data in row to named values according to row_map" do 274 | row_map = @filing.send(:mappings).for_row(@sa_row.first) 275 | mapped = @filing.send(:map, @sa_row) 276 | mapped.should be_a_kind_of(Hash) 277 | 278 | mapped[:form_type].should == "SA17A" 279 | mapped[:contributor_state].should == "SC" 280 | 281 | row_map_ie = @filing_ie.send(:mappings).for_row(@se_row.first) 282 | mapped_ie = @filing_ie.send(:map, @se_row) 283 | mapped_ie.should be_a_kind_of(Hash) 284 | 285 | mapped_ie[:form_type].should == "SE" 286 | mapped_ie[:candidate_id_number].should == "P00003608" 287 | end 288 | 289 | it "should perform conversion translations" do 290 | row_map = @filing.send(:mappings).for_row(@sa_row.first) 291 | @filing.translate do |t| 292 | t.convert(:row => @sa_row.first, :field => :contribution_date) do |v| 293 | Date.parse(v) 294 | end 295 | end 296 | mapped = @filing.send(:map, @sa_row) 297 | mapped[:contribution_date].should == Date.parse("20110322") 298 | end 299 | 300 | it "should perform combination translations" do 301 | @filing.translate do |t| 302 | t.combine(:row => @f3p_row.first, :field => :net_individual_contributions) do |row| 303 | row[:col_a_17_a_iii_individual_contribution_total].to_f - row[:col_a_28_a_individuals].to_f 304 | end 305 | end 306 | mapped = @filing.send(:map, @f3p_row) 307 | mapped[:net_individual_contributions].should == mapped[:col_a_17_a_iii_individual_contribution_total].to_f - mapped[:col_a_28_a_individuals].to_f 308 | end 309 | 310 | it "should return only field asked for if :include was specified" do 311 | fields = [:form_type, :filer_committee_id_number, :transaction_id] 312 | mapped = @filing.send(:map, @sa_row, :include => fields) 313 | fields.each do |field| 314 | mapped[field].should_not be_nil 315 | end 316 | mapped.size.should == 3 317 | end 318 | 319 | end 320 | 321 | describe "amendments" do 322 | 323 | before do 324 | @filing = Fech::Filing.new(723604) 325 | @filing.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '723604.fec')) 326 | end 327 | 328 | describe "for non-amending filings" do 329 | 330 | describe "#amendment?" do 331 | it "should return false" do 332 | @filing.stubs(:header).returns({:report_id => nil}) 333 | @filing.amendment?.should == false 334 | end 335 | end 336 | 337 | end 338 | 339 | describe "#amends" do 340 | 341 | it "should return nil for filings without a report_id in HDR" do 342 | @filing.stubs(:header).returns({:report_id => nil}) 343 | @filing.amends.should == nil 344 | end 345 | 346 | it "should return a filing_id for filings with a report_id in HDR" do 347 | @filing.stubs(:header).returns({:report_id => "723603"}) 348 | @filing.amends.should == "723603" 349 | end 350 | 351 | end 352 | 353 | describe "#amendment?" do 354 | 355 | it "should return false for filings without a report_id in HDR" do 356 | @filing.stubs(:header).returns({:report_id => nil}) 357 | @filing.amendment?.should == false 358 | end 359 | 360 | it "should return true for filings with a report_id in HDR" do 361 | @filing.stubs(:header).returns({:report_id => "723603"}) 362 | @filing.amendment?.should == true 363 | end 364 | 365 | end 366 | end 367 | end 368 | -------------------------------------------------------------------------------- /spec/map_generator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Fech::MapGenerator do 4 | 5 | describe ".generate_row_map_from_file" do 6 | 7 | before do 8 | @mg = Fech::MapGenerator.new 9 | @row = "sa" 10 | @source_dir = File.join(File.dirname(__FILE__), 'sources', @row + '.csv') 11 | Fech::MapGenerator.stubs(:row_map_file).returns(@source_dir) 12 | end 13 | 14 | it "should not raise error on bad data" do 15 | lambda { 16 | Fech::MapGenerator.generate_row_map_from_file(@source_dir, @row) 17 | }.should_not raise_error 18 | end 19 | 20 | it "should skip rows without a canonical name" do 21 | row_map = Fech::MapGenerator.generate_row_map_from_file(@source_dir, @row) 22 | row_map["^7"].should == [:form_type, :date_coverage_from, :aggregate] 23 | end 24 | 25 | it "should skip columns without a version_type header" do 26 | row_map = Fech::MapGenerator.generate_row_map_from_file(@source_dir, @row) 27 | row_map.keys.should =~ ["^7", "^6", "^[2-5]"] 28 | end 29 | 30 | it "should not add items where there is no index" do 31 | row_map = Fech::MapGenerator.generate_row_map_from_file(@source_dir, @row) 32 | row_map["^6"][1].should be_nil 33 | end 34 | 35 | end 36 | 37 | describe ".convert_header_file_to_row_files" do 38 | before do 39 | @source_dir = File.join(File.dirname(__FILE__), 'sources') 40 | end 41 | it "should not raise error" do 42 | Fech::MapGenerator.convert_header_file_to_row_files(@source_dir) 43 | lambda { 44 | Fech::MapGenerator.convert_header_file_to_row_files(@source_dir) 45 | }.should_not raise_error 46 | end 47 | end 48 | 49 | end -------------------------------------------------------------------------------- /spec/mapped_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Fech::Mapped do 4 | 5 | before do 6 | @f = Fech::Filing.new(723604) 7 | @f.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '723604.fec')) 8 | end 9 | 10 | describe "@filing" do 11 | 12 | it "should get set to the calling filing" do 13 | header = @f.header 14 | header.should be_a_kind_of Fech::Mapped 15 | header.filing.should == @f 16 | end 17 | 18 | end 19 | 20 | describe "[]" do 21 | 22 | it "should obey aliases in the filing's translator" do 23 | @f.translate do |t| 24 | t.alias :version, :fec_version, "hdr" 25 | end 26 | 27 | header = @f.header 28 | header[:version].should == header[:fec_version] 29 | end 30 | 31 | it "should detect the most recent alias first" do 32 | @f.translate do |t| 33 | t.alias :version, :fec_version, "hdr" 34 | t.alias :version, :report_id, "hdr" 35 | end 36 | 37 | header = @f.header 38 | header[:version].should_not == header[:fec_version] 39 | header[:version].should == header[:report_id] 40 | end 41 | 42 | end 43 | 44 | end -------------------------------------------------------------------------------- /spec/mappings_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Fech::Mappings do 4 | 5 | describe "#for_row" do 6 | 7 | before do 8 | @mappings = Fech::Mappings.new 9 | end 10 | 11 | it "should return the correct row_map" do 12 | @mappings.for_row("sa").should == @mappings.map["^sa"]["^8.1|8.0"] 13 | @mappings.for_row("f3p31").should_not == @mappings.for_row("f3p") 14 | end 15 | 16 | it "should use a greedy match on the row type, matching most complete available option" do 17 | @mappings.for_row("f3p31").should == @mappings.map[FechUtils::ROW_TYPES[:f3p31].source]["^8.1|8.0|7.0|6.4|6.3|6.2|6.1"] 18 | @mappings.for_row("f3p").should == @mappings.map[FechUtils::ROW_TYPES[:f3p].source]["^8.1|8.0|7.0"] 19 | end 20 | 21 | end 22 | 23 | describe ".key_by_regex" do 24 | 25 | before do 26 | @hash = { 27 | "^foo$" => :foo, 28 | "bar" => :bar 29 | } 30 | end 31 | 32 | it "should match a key by regexp" do 33 | Fech::Mappings.key_by_regex(@hash, "foo").should == :foo 34 | Fech::Mappings.key_by_regex(@hash, "bar").should == :bar 35 | Fech::Mappings.key_by_regex(@hash, "foobar").should == :bar 36 | end 37 | 38 | it "raise error if key not found" do 39 | expect { 40 | Fech::Mappings.key_by_regex(@hash, "oof") 41 | }.to raise_error 42 | end 43 | 44 | end 45 | 46 | end -------------------------------------------------------------------------------- /spec/sources/F24.csv: -------------------------------------------------------------------------------- 1 | canonical,^8.0,,^7.0|6.4|6.3|6.2|6.1,,^5.0|5.1|5.2|5.3,,^3, 2 | form_type,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE 3 | filer_committee_id_number,2,FILER COMMITTEE ID NUMBER,2,FILER COMMITTEE ID NUMBER,2,FILER COMMITTEE ID NUMBER,2,FILER FEC CMTE ID 4 | report_type,3,REPORT TYPE {24/48 Hour},3,REPORT TYPE {24/48 Hour},11,REPORT TYPE,, 5 | original_amendment_date,4,ORIGINAL AMENDMENT DATE,, 6 | committee_name,5,COMMITTEE NAME,4,COMMITTEE NAME,3,COMMITTEE NAME,3,COMMITTEE NAME 7 | street_1,6,STREET 1,5,STREET 1,4,STREET 1,4,STREET 1 8 | street_2,7,STREET 1,6,STREET 2,5,STREET 2,5,STREET 2 9 | city,8,CITY,7,CITY,6,CITY,6,CITY 10 | state,9,STATE,8,STATE,7,STATE,7,STATE 11 | zip,10,ZIP,9,ZIP,8,ZIP,8,ZIP 12 | treasurer_name,,,,9,NAME/TREASURER (as signed),9,NAME/TREASURER (as signed) 13 | treasurer_last_name,11,TREASURER LAST NAME,10,TREASURER LAST NAME,,,, 14 | treasurer_first_name,12,TREASURER FIRST NAME,11,TREASURER FIRST NAME,,,, 15 | treasurer_middle_name,13,TREASURER MIDDLE NAME,12,TREASURER MIDDLE NAME,,,, 16 | treasurer_prefix,14,TREASURER PREFIX,13,TREASURER PREFIX,,,, 17 | treasurer_suffix,15,TREASURER SUFFIX,14,TREASURER SUFFIX,,,, 18 | date_signed,16,DATE SIGNED,15,DATE SIGNED,10,DATE (Signed),10,DATE (Signed) 19 | -------------------------------------------------------------------------------- /spec/sources/F3P.csv: -------------------------------------------------------------------------------- 1 | canonical,^7.0|8.0,,^6.4|6.3|6.2|6.1,,^5.3|5.2,,^5.1|5.0|3, form_type,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE filer_committee_id_number,2,FILER COMMITTEE ID NUMBER,2,FILER COMMITTEE ID NUMBER,2,FILER FEC CMTE ID,2,FILER FEC CMTE ID committee_name,3,COMMITTEE NAME,3,COMMITTEE NAME,3,COMMITTEENAME,3,COMMITTEENAME change_of_address,4,CHANGE OF ADDRESS,4,CHANGE OF ADDRESS,9,CHG OF ADDRESS,9,CHG OF ADDRESS street_1,5,STREET 1,5,STREET 1,4,STREET 1,4,STREET 1 street_2,6,STREET 2,6,STREET 2,5,STREET 2,5,STREET 2 city,7,CITY,7,CITY,6,CITY,6,CITY state,8,STATE,8,STATE,7,STATE,7,STATE zip,9,ZIP,9,ZIP,8,ZIP,8,ZIP activity_primary,10,ACTIVITY PRIMARY,10,ACTIVITY PRIMARY,10,ACTIVITY PRIMARY,10,ACTIVITY PRIMARY activity_general,11,ACTIVITY GENERAL,11,ACTIVITY GENERAL,11,ACTIVITY GENERAL,11,ACTIVITY GENERAL report_code,12,REPORT CODE,12,REPORT CODE,12,RPTCODE,12,RPTCODE election_code,13,ELECTION CODE {was RPTPGI},13,ELECTION CODE {was RPTPGI},13,RPTPGI,13,RPTPGI date_of_election,14,DATE OF ELECTION,14,DATE OF ELECTION,14,DATE (Of Election),14,DATE (Of Election) state_of_election,15,STATE OF ELECTION,15,STATE OF ELECTION,15,STATE (Of Election),15,STATE (Of Election) coverage_from_date,16,COVERAGE FROM DATE,16,COVERAGE FROM DATE,16,DATE (Coverage From),16,DATE (Coverage From) coverage_through_date,17,COVERAGE THROUGH DATE,17,COVERAGE THROUGH DATE,17,DATE (Coverage To),17,DATE (Coverage To) treasurer_name,,,,,197,NAME/TREASURER (as signed),197,NAME/TREASURER (as signed) treasurer_last_name,18,TREASURER LAST NAME,18,TREASURER LAST NAME,,,, treasurer_first_name,19,TREASURER FIRST NAME,19,TREASURER FIRST NAME,,,, treasurer_middle_name,20,TREASURER MIDDLE NAME,20,TREASURER MIDDLE NAME,,,, treasurer_prefix,21,TREASURER PREFIX,21,TREASURER PREFIX,,,, treasurer_suffix,22,TREASURER SUFFIX,22,TREASURER SUFFIX,,,, date_signed,23,DATE SIGNED,23,DATE SIGNED,198,DATE (Signed),198,DATE (Signed) col_a_cash_on_hand_beginning_period,24,6. Cash on Hand Beginning Period,24,6. Cash on Hand Beginning Period,18,6. Cash on Hand Beginning Period,18,6. Cash on Hand Beginning Period col_a_total_receipts,25,7. Total Receipts,25,7. Total Receipts,19,7. Total Receipts,19,7. Total Receipts col_a_subtotal,26,8. Subtotal,26,8. SubTotal,20,8. SubTotal,20,8. SubTotal col_a_total_disbursements,27,9. Total Disbursements,27,9. Total Disbursements,21,9. Total Disbursements,21,9. Total Disbursements col_a_cash_on_hand_close_of_period,28,10. Cash on Hand Close of Period,28,10. Cash on Hand Close of Period,22,10. Cash on Hand Close of Period,22,10. Cash on Hand Close of Period col_a_debts_to,29,11. Debts to,29,11. Debts to,23,11. Debts to,23,11. Debts to col_a_debts_by,30,12. Debts by,30,12. Debts by,24,12. Debts by,24,12. Debts by col_a_expenditures_subject_to_limits,31,13. Expenditures Subject to Limits,31,13. Expenditures Subject to Limits,25,13. Expenditures Subject to Limits,25,13. Expenditures Subject to Limits col_a_net_contributions,32,14. Net Contributions,32,14. Net Contributions,26,14. Net Contributions,26,14. Net Contributions col_a_net_operating_expenditures,33,15. Net Operating Expenditures,33,15. Net Operating Expenditures,27,15. Net Operating Expenditures,27,15. Net Operating Expenditures col_a_federal_funds,34,16. Federal Funds,34,16. Federal Funds,28,16. Federal Funds,28,16. Federal Funds col_a_individuals_itemized,35,17(a.i) Individuals Itemized,,,,,, col_a_individuals_unitemized,36,17(a.ii) Individuals Unitemized,,,,,, col_a_individual_contribution_total,37,17(a.iii) Individual Contribution Total,35,17(a) Individuals,29,17(a) Individuals,29,17(a) Individuals col_a_political_party_committees,38,17(b) Political Party Committees,36,17(b) Political Party Committees,30,17(b) Political Party Committees,30,17(b) Political Party Committees col_a_other_political_committees_pacs,39,17(c) Other Political Committees (PACs),37,17(c) Other Political Committees (PACs),31,17(c) Other Political Committees (PACs),31,17(c) Other Political Committees (PACs) col_a_the_candidate,40,17(d) The Candidate,38,17(d) The Candidate,32,17(d) The Candidate,32,17(d) The Candidate col_a_total_contributions,41,17(e) Total Contributions,39,17(e) Total Contributions,33,17(e) Total Contributions,33,17(e) Total Contributions col_a_transfers_from_aff_other_party_cmttees,42,18. Transfers From Aff/Other Party Cmttees,40,18. Transfers From Aff/Other Party Cmttees,34,18. Transfers From Aff/Other Party Cmttees,34,18. Transfers From Aff/Other Party Committees col_a_received_from_or_guaranteed_by_cand,43,19(a) Received from or Guaranteed by Cand.,41,19(a) Received from or Guaranteed by Cand.,35,19(a) Received from or Guaranteed by Cand.,35,19(a) Received from or Guaranteed by Candidate col_a_other_loans,44,19(b) Other Loans,42,19(b) Other Loans,36,19(b) Other Loans,36,19(b) Other Loans col_a_total_loans,45,19(c) Total Loans,43,19(c) Total Loans,37,19(c) Total Loans,37,19(c) Total Loans col_a_operating,46,20(a) Operating,44,20(a) Operating,38,20(a) Operating,38,20(a) Operating col_a_fundraising,47,20(b) Fundraising,45,20(b) Fundraising,39,20(b) Fundraising,39,20(b) Fundraising col_a_legal_and_accounting,48,20(c) Legal and Accounting,46,20(c) Legal and Accounting,40,20(c) Legal and Accounting,40,20(c) Legal and Accounting col_a_total_offsets_to_expenditures,49,20(d) Total offsets to Expenditures,47,20(d) Total offsets to Expenditures,41,20(d) Total offsets to Expenditures,41,20(d) Total offsets to Expenditures col_a_other_receipts,50,21. Other Receipts,48,21. Other Receipts,42,21. Other Receipts,42,21. Other Receipts col_a_total_receipts,51,22. Total Receipts,49,22. Total Receipts,43,22. Total Receipts,43,22. Total Receipts col_a_operating_expenditures,52,23. Operating Expenditures,50,23. Operating Expenditures,44,23. Operating Expenditures,44,23. Operating Expenditures col_a_transfers_to_other_authorized_committees,53,24. Transfers to Other Authorized Committees,51,24. Transfers to Other Authorized Committees,45,24. Transfers to Other Authorized Committees,45,24. Transfers to Other Authorized Committees col_a_fundraising_disbursements,54,25. Fundraising Disbursements,52,25. Fundraising Disbursements,46,25. Fundraising Disbursements,46,25. Fundraising Disbursements col_a_exempt_legal_accounting_disbursement,55,26. Exempt Legal & Accounting Disbursement,53,26. Exempt Legal & Accounting Disbursement,47,26. Exempt Legal & Accounting Disbursement,47,26. Exempt Legal and Accounting Disbursements col_a_made_or_guaranteed_by_candidate,56,27(a) Made or guaranteed by Candidate,54,27(a) Made or guaranteed by Candidate,48,27(a) Made or guaranteed by Candidate,48,27(a) Made or guaranteed by Candidate col_a_other_repayments,57,27(b) Other Repayments,55,27(b) Other Repayments,49,27(b) Other Repayments,49,27(b) Other Repayments col_a_total_loan_repayments_made,58,27(c) Total Loan Repayments Made,56,27(c) Total Loan Repayments Made,50,27(c) Total Loan Repayments Made,50,27(c) Total Loan Repayments Made col_a_individuals,59,28(a) Individuals,57,28(a) Individuals,51,28(a) Individuals,51,28(a) Individuals col_a_political_party_committees,60,28(b) Political Party Committees,58,28(b) Political Party Committees,52,28(b) Political Party Committees,52,28(b) Political Party Committees col_a_other_political_committees,61,28(c) Other Political Committees,59,28(c) Other Political Committees,53,28(c) Other Political Committees,53,28(c) Other Political Committees col_a_total_contributions_refunds,62,28(d) Total Contributions Refunds,60,28(d) Total Contributions Refunds,54,28(d) Total Contributions Refunds,54,28(d) Total Contributions Refunds col_a_other_disbursements,63,29. Other Disbursements,61,29. Other Disbursements,55,29. Other Disbursements,55,29. Other Disbursements col_a_total_disbursements,64,30. Total Disbursements,62,30. Total Disbursements,56,30. Total Disbursements,56,30. Total Disbursements col_a_items_on_hand_to_be_liquidated,65,31. Items on Hand to be Liquidated,63,31. Items on Hand to be Liquidated,57,31. Items on Hand to be Liquidated,57,31. Items on Hand to be Liquidated col_a_alabama,66,ALABAMA,64,ALABAMA,58,ALABAMA,58,ALABAMA col_a_alaska,67,ALASKA,65,ALASKA,59,ALASKA,59,ALASKA col_a_arizona,68,ARIZONA,66,ARIZONA,60,ARIZONA,60,ARIZONA col_a_arkansas,69,ARKANSAS,67,ARKANSAS,61,ARKANSAS,61,ARKANSAS col_a_california,70,CALIFORNIA,68,CALIFORNIA,62,CALIFORNIA,62,CALIFORNIA col_a_colorado,71,COLORADO,69,COLORADO,63,COLORADO,63,COLORADO col_a_connecticut,72,CONNECTICUT,70,CONNECTICUT,64,CONNECTICUT,64,CONNECTICUT col_a_delaware,73,DELAWARE,71,DELAWARE,65,DELAWARE,65,DELAWARE col_a_dist_of_columbia,74,DIST OF COLUMBIA,72,DIST OF COLUMBIA,66,DIST OF COLUMBIA,66,DIST OF COLUMBIA col_a_florida,75,FLORIDA,73,FLORIDA,67,FLORIDA,67,FLORIDA col_a_georgia,76,GEORGIA,74,GEORGIA,68,GEORGIA,68,GEORGIA col_a_hawaii,77, HAWAII,75, HAWAII,69, HAWAII,69, HAWAII col_a_idaho,78,IDAHO,76,IDAHO,70,IDAHO,70,IDAHO col_a_illinois,79,ILLINOIS,77,ILLINOIS,71,ILLINOIS,71,ILLINOIS col_a_indiana,80,INDIANA,78,INDIANA,72,INDIANA,72,INDIANA col_a_iowa,81,IOWA,79,IOWA,73,IOWA,73,IOWA col_a_kansas,82,KANSAS,80,KANSAS,74,KANSAS,74,KANSAS col_a_kentucky,83,KENTUCKY,81,KENTUCKY,75,KENTUCKY,75,KENTUCKY col_a_louisiana,84,LOUISIANA,82,LOUISIANA,76,LOUISIANA,76,LOUISIANA col_a_maine,85,MAINE,83,MAINE,77,MAINE,77,MAINE col_a_maryland,86,MARYLAND,84,MARYLAND,78,MARYLAND,78,MARYLAND col_a_massachusetts,87,MASSACHUSETTS,85,MASSACHUSETTS,79,MASSACHUSETTS,79,MASSACHUSETTS col_a_michigan,88,MICHIGAN,86,MICHIGAN,80,MICHIGAN,80,MICHIGAN col_a_minnesota,89,MINNESOTA,87,MINNESOTA,81,MINNESOTA,81,MINNESOTA col_a_mississippi,90,MISSISSIPPI,88,MISSISSIPPI,82,MISSISSIPPI,82,MISSISSIPPI col_a_missouri,91,MISSOURI,89,MISSOURI,83,MISSOURI,83,MISSOURI col_a_montana,92, MONTANA,90, MONTANA,84, MONTANA,84, MONTANA col_a_nebraska,93,NEBRASKA,91,NEBRASKA,85,NEBRASKA,85,NEBRASKA col_a_nevada,94,NEVADA,92,NEVADA,86,NEVADA,86,NEVADA col_a_new_hampshire,95,NEW HAMPSHIRE,93,NEW HAMPSHIRE,87,NEW HAMPSHIRE,87,NEW HAMPSHIRE col_a_new_jersey,96,NEW JERSEY,94,NEW JERSEY,88,NEW JERSEY,88,NEW JERSEY col_a_new_mexico,97,NEW MEXICO,95,NEW MEXICO,89,NEW MEXICO,89,NEW MEXICO col_a_new_york,98,NEW YORK,96,NEW YORK,90,NEW YORK,90,NEW YORK col_a_north_carolina,99,NORTH CAROLINA,97,NORTH CAROLINA,91,NORTH CAROLINA,91,NORTH CAROLINA col_a_north_dakota,100,NORTH DAKOTA,98,NORTH DAKOTA,92,NORTH DAKOTA,92,NORTH DAKOTA col_a_ohio,101,OHIO,99,OHIO,93,OHIO,93,OHIO col_a_oklahoma,102,OKLAHOMA,100,OKLAHOMA,94,OKLAHOMA,94,OKLAHOMA col_a_oregon,103,OREGON,101,OREGON,95,OREGON,95,OREGON col_a_pennsylvania,104,PENNSYLVANIA,102,PENNSYLVANIA,96,PENNSYLVANIA,96,PENNSYLVANIA col_a_rhode_island,105,RHODE ISLAND,103,RHODE ISLAND,97,RHODE ISLAND,97,RHODE ISLAND col_a_south_carolina,106,SOUTH CAROLINA,104,SOUTH CAROLINA,98,SOUTH CAROLINA,98,SOUTH CAROLINA col_a_south_dakota,107,SOUTH DAKOTA,105,SOUTH DAKOTA,99,SOUTH DAKOTA,99,SOUTH DAKOTA col_a_tennessee,108,TENNESSEE,106,TENNESSEE,100,TENNESSEE,100,TENNESSEE col_a_texas,109,TEXAS,107,TEXAS,101,TEXAS,101,TEXAS col_a_utah,110,UTAH,108,UTAH,102,UTAH,102,UTAH col_a_vermont,111,VERMONT,109,VERMONT,103,VERMONT,103,VERMONT col_a_virginia,112,VIRGINIA,110,VIRGINIA,104,VIRGINIA,104,VIRGINIA col_a_washington,113,WASHINGTON,111,WASHINGTON,105,WASHINGTON,105,WASHINGTON col_a_west_virginia,114,WEST VIRGINIA,112,WEST VIRGINIA,106,WEST VIRGINIA,106,WEST VIRGINIA col_a_wisconsin,115,WISCONSIN,113,WISCONSIN,107,WISCONSIN,107,WISCONSIN col_a_wyoming,116,WYOMING,114,WYOMING,108,WYOMING,108,WYOMING col_a_puerto_rico,117,PUERTO RICO,115,PUERTO RICO,109,PUERTO RICO,109,PUERTO RICO col_a_guam,118,GUAM,116,GUAM,110,GUAM,110,GUAM col_a_virgin_islands,119,VIRGIN ISLANDS,117,VIRGIN ISLANDS,111,VIRGIN ISLANDS,111,VIRGIN ISLANDS col_a_totals,120,TOTALS,118,TOTALS,112,TOTALS,112,TOTALS col_b_federal_funds,121,16. Federal Funds,119,16. Federal Funds,113,16. Federal Funds,113,16. Federal Funds col_b_individuals_itemized,122,17(a.i) Individuals Itemized,,,,,, col_b_individuals_unitemized,123,17(a.ii) Individuals Unitemized,,,,,, col_b_individual_contribution_total,124,17(a.iii) Individual Contribution Total,120,17(a) Individuals,114,17(a) Individuals,114,17(a) Individuals col_b_political_party_committees,125,17(b) Political Party Committees,121,17(b) Political Party Committees,115,17(b) Political Party Committees,115,17(b) Political Party Committees col_b_other_political_committees_pacs,126,17(c) Other Political Committees (PACs),122,17(c) Other Political Committees (PACs),116,17(c) Other Political Committees (PACs),116,17(c) Other Political Committees (PACs) col_b_the_candidate,127,17(d) The Candidate,123,17(d) The Candidate,117,17(d) The Candidate,117,17(d) The Candidate col_b_total_contributions_other_than_loans,128,17(e) Total contributions (Other than Loans),124,17(e) Total contributions (Other than Loans),118,17(e) Total contributions (Other than Loans),118,17(e) Total contributions (Other than Loans) col_b_transfers_from_aff_other_party_cmttees,129,18. Transfers From Aff/Other Party Cmttees,125,18. Transfers From Aff/Other Party Cmttees,119,18. Transfers From Aff/Other Party Cmttees,119,18. Transfers From Aff/Other Party Committees col_b_received_from_or_guaranteed_by_cand,130,19(a) Received from or Guaranteed by Cand.,126,19(a) Received from or Guaranteed by Cand.,120,19(a) Received from or Guaranteed by Cand.,120,19(a) Received from or Guaranteed by Candidate col_b_other_loans,131,19(b) Other Loans,127,19(b) Other Loans,121,19(b) Other Loans,121,19(b) Other Loans col_b_total_loans,132,19(c) Total Loans,128,19(c) Total Loans,122,19(c) Total Loans,122,19(c) Total Loans col_b_operating,133,20(a) Operating,129,20(a) Operating,123,20(a) Operating,123,20(a) Operating col_b_fundraising,134,20(b) Fundraising,130,20(b) Fundraising,124,20(b) Fundraising,124,20(b) Fundraising col_b_legal_and_accounting,135,20(c) Legal and Accounting,131,20(c) Legal and Accounting,125,20(c) Legal and Accounting,125,20(c) Legal and Accounting col_b_total_offsets_to_operating_expenditures,136,20(d) Total Offsets to Operating Expenditures,132,20(d) Total Offsets to Operating Expenditures,126,20(d) Total Offsets to Operating Expenditures,126,20(d) Total Offsets to Operating Expenditures col_b_other_receipts,137,21. Other Receipts,133,21. Other Receipts,127,21. Other Receipts,127,21. Other Receipts col_b_total_receipts,138,22. Total Receipts,134,22. Total Receipts,128,22. Total Receipts,128,22. Total Receipts col_b_operating_expenditures,139,23. Operating Expenditures,135,23. Operating Expenditures,129,23. Operating Expenditures,129,23. Operating Expenditures col_b_transfers_to_other_authorized_committees,140,24. Transfers to Other Authorized Committees,136,24. Transfers to Other Authorized Committees,130,24. Transfers to Other Authorized Committees,130,24. Transfers to Other Authorized Committees col_b_fundraising_disbursements,141,25. Fundraising Disbursements,137,25. Fundraising Disbursements,131,25. Fundraising Disbursements,131,25. Fundraising Disbursements col_b_exempt_legal_accounting_disbursement,142,26. Exempt Legal & Accounting Disbursement,138,26. Exempt Legal & Accounting Disbursement,132,26. Exempt Legal & Accounting Disbursement,132,26. Exempt Legal and Accounting Disbursements col_b_made_or_guaranteed_by_the_candidate,143,27(a) Made or Guaranteed by the Candidate,139,27(a) Made or Guaranteed by the Candidate,133,27(a) Made or Guaranteed by the Candidate,133,27(a) Made or Guaranteed by the Candidate col_b_other_repayments,144,27(b) Other Repayments,140,27(b) Other Repayments,134,27(b) Other Repayments,134,27(b) Other Repayments col_b_total_loan_repayments_made,145,27(c) Total Loan Repayments Made,141,27(c) Total Loan Repayments Made,135,27(c) Total Loan Repayments Made,135,27(c) Total Loan Repayments Made col_b_individuals,146,28(a) Individuals,142,28(a) Individuals,136,28(a) Individuals,136,28(a) Individuals col_b_political_party_committees,147,28(b) Political Party Committees,143,28(b) Political Party Committees,137,28(b) Political Party Committees,137,28(b) Political Party Committees col_b_other_political_committees,148,28(c) Other Political Committees,144,28(c) Other Political Committees,138,28(c) Other Political Committees,138,28(c) Other Political Committees col_b_total_contributions_refunds,149,28(d) Total Contributions Refunds,145,28(d) Total Contributions Refunds,139,28(d) Total Contributions Refunds,139,28(d) Total Contributions Refunds col_b_other_disbursements,150,29. Other Disbursements,146,29. Other Disbursements,140,29. Other Disbursements,140,29. Other Disbursements col_b_total_disbursements,151,30. Total Disbursements,147,30. Total Disbursements,141,30. Total Disbursements,141,30. Total Disbursements col_b_alabama,152,ALABAMA,148,ALABAMA,142,ALABAMA,142,ALABAMA col_b_alaska,153,ALASKA,149,ALASKA,143,ALASKA,143,ALASKA col_b_arizona,154,ARIZONA,150,ARIZONA,144,ARIZONA,144,ARIZONA col_b_arkansas,155,ARKANSAS,151,ARKANSAS,145,ARKANSAS,145,ARKANSAS col_b_california,156,CALIFORNIA,152,CALIFORNIA,146,CALIFORNIA,146,CALIFORNIA col_b_colorado,157,COLORADO,153,COLORADO,147,COLORADO,147,COLORADO col_b_connecticut,158,CONNECTICUT,154,CONNECTICUT,148,CONNECTICUT,148,CONNECTICUT col_b_delaware,159,DELAWARE,155,DELAWARE,149,DELAWARE,149,DELAWARE col_b_dist_of_columbia,160,DIST OF COLUMBIA,156,DIST OF COLUMBIA,150,DIST OF COLUMBIA,150,DIST OF COLUMBIA col_b_florida,161,FLORIDA,157,FLORIDA,151,FLORIDA,151,FLORIDA col_b_georgia,162,GEORGIA,158,GEORGIA,152,GEORGIA,152,GEORGIA col_b_hawaii,163,HAWAII,159,HAWAII,153,HAWAII,153,HAWAII col_b_idaho,164,IDAHO,160,IDAHO,154,IDAHO,154,IDAHO col_b_illinois,165,ILLINOIS,161,ILLINOIS,155,ILLINOIS,155,ILLINOIS col_b_indiana,166,INDIANA,162,INDIANA,156,INDIANA,156,INDIANA col_b_iowa,167,IOWA,163,IOWA,157,IOWA,157,IOWA col_b_kansas,168,KANSAS,164,KANSAS,158,KANSAS,158,KANSAS col_b_kentucky,169,KENTUCKY,165,KENTUCKY,159,KENTUCKY,159,KENTUCKY col_b_louisiana,170,LOUISIANA,166,LOUISIANA,160,LOUISIANA,160,LOUISIANA col_b_maine,171,MAINE,167,MAINE,161,MAINE,161,MAINE col_b_maryland,172,MARYLAND,168,MARYLAND,162,MARYLAND,162,MARYLAND col_b_massachusetts,173,MASSACHUSETTS,169,MASSACHUSETTS,163,MASSACHUSETTS,163,MASSACHUSETTS col_b_michigan,174,MICHIGAN,170,MICHIGAN,164,MICHIGAN,164,MICHIGAN col_b_minnesota,175,MINNESOTA,171,MINNESOTA,165,MINNESOTA,165,MINNESOTA col_b_mississippi,176,MISSISSIPPI,172,MISSISSIPPI,166,MISSISSIPPI,166,MISSISSIPPI col_b_missouri,177,MISSOURI,173,MISSOURI,167,MISSOURI,167,MISSOURI col_b_montana,178,MONTANA,174,MONTANA,168,MONTANA,168,MONTANA col_b_nebraska,179,NEBRASKA,175,NEBRASKA,169,NEBRASKA,169,NEBRASKA col_b_nevada,180,NEVADA,176,NEVADA,170,NEVADA,170,NEVADA col_b_new_hampshire,181,NEW HAMPSHIRE,177,NEW HAMPSHIRE,171,NEW HAMPSHIRE,171,NEW HAMPSHIRE col_b_new_jersey,182,NEW JERSEY,178,NEW JERSEY,172,NEW JERSEY,172,NEW JERSEY col_b_new_mexico,183,NEW MEXICO,179,NEW MEXICO,173,NEW MEXICO,173,NEW MEXICO col_b_new_york,184,NEW YORK,180,NEW YORK,174,NEW YORK,174,NEW YORK col_b_north_carolina,185,NORTH CAROLINA,181,NORTH CAROLINA,175,NORTH CAROLINA,175,NORTH CAROLINA col_b_north_dakota,186,NORTH DAKOTA,182,NORTH DAKOTA,176,NORTH DAKOTA,176,NORTH DAKOTA col_b_ohio,187,OHIO,183,OHIO,177,OHIO,177,OHIO col_b_oklahoma,188,OKLAHOMA,184,OKLAHOMA,178,OKLAHOMA,178,OKLAHOMA col_b_oregon,189,OREGON,185,OREGON,179,OREGON,179,OREGON col_b_pennsylvania,190,PENNSYLVANIA,186,PENNSYLVANIA,180,PENNSYLVANIA,180,PENNSYLVANIA col_b_rhode_island,191,RHODE ISLAND,187,RHODE ISLAND,181,RHODE ISLAND,181,RHODE ISLAND col_b_south_carolina,192,SOUTH CAROLINA,188,SOUTH CAROLINA,182,SOUTH CAROLINA,182,SOUTH CAROLINA col_b_south_dakota,193,SOUTH DAKOTA,189,SOUTH DAKOTA,183,SOUTH DAKOTA,183,SOUTH DAKOTA col_b_tennessee,194,TENNESSEE,190,TENNESSEE,184,TENNESSEE,184,TENNESSEE col_b_texas,195,TEXAS,191,TEXAS,185,TEXAS,185,TEXAS col_b_utah,196,UTAH,192,UTAH,186,UTAH,186,UTAH col_b_vermont,197,VERMONT,193,VERMONT,187,VERMONT,187,VERMONT col_b_virginia,198,VIRGINIA,194,VIRGINIA,188,VIRGINIA,188,VIRGINIA col_b_washington,199,WASHINGTON,195,WASHINGTON,189,WASHINGTON,189,WASHINGTON col_b_west_virginia,200,WEST VIRGINIA,196,WEST VIRGINIA,190,WEST VIRGINIA,190,WEST VIRGINIA col_b_wisconsin,201,WISCONSIN,197,WISCONSIN,191,WISCONSIN,191,WISCONSIN col_b_wyoming,202,WYOMING,198,WYOMING,192,WYOMING,192,WYOMING col_b_puerto_rico,203,PUERTO RICO,199,PUERTO RICO,193,PUERTO RICO,193,PUERTO RICO col_b_guam,204,GUAM,200,GUAM,194,GUAM,194,GUAM col_b_virgin_islands,205,VIRGIN ISLANDS,201,VIRGIN ISLANDS,195,VIRGIN ISLANDS,195,VIRGIN ISLANDS col_b_totals,206,TOTALS,202,TOTALS,196,TOTALS,196,TOTALS -------------------------------------------------------------------------------- /spec/sources/F3P31.csv: -------------------------------------------------------------------------------- 1 | canonical,^8.0|7.0|6.4|6.3|6.2|6.1,,^5.3,,^5.2|5.1|5.0|3, 2 | form_type,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE 3 | filer_committee_id_number,2,FILER COMMITTEE ID NUMBER,2,FILER FEC CMTE ID,2,FILER FEC CMTE ID 4 | transaction_id_number,3,TRANSACTION ID NUMBER,32,TRAN ID,32,TRAN ID 5 | entity_type,4,ENTITY TYPE,3,ENTITY TYPE,3,ENTITY TYPE 6 | contributor_organization_name,5,CONTRIBUTOR ORGANIZATION NAME ,-0,,-0, 7 | contributor_name,,,4,NAME (Contributor/Lender),4,NAME (Contributor/Lender) 8 | contributor_last_name,6,CONTRIBUTOR LAST NAME,-0,,-0, 9 | contributor_first_name,7,CONTRIBUTOR FIRST NAME,-0,,-0, 10 | contributor_middle_name,8,CONTRIBUTOR MIDDLE NAME,-0,,-0, 11 | contributor_prefix,9,CONTRIBUTOR PREFIX,-0,,-0, 12 | contributor_suffix,10,CONTRIBUTOR SUFFIX,-0,,-0, 13 | contributor_street_1,11,CONTRIBUTOR STREET 1,5,STREET 1,5,STREET 1 14 | contributor_street_2,12,CONTRIBUTOR STREET 2,6,STREET 2,6,STREET 2 15 | contributor_city,13,CONTRIBUTOR CITY,7,CITY,7,CITY 16 | contributor_state,14,CONTRIBUTOR STATE,8,STATE,8,STATE 17 | contributor_zip,15,CONTRIBUTOR ZIP,9,ZIP,9,ZIP 18 | election_code,16,ELECTION CODE {was RPTPGI},10,RPTPGI,10,RPTPGI 19 | item_description,17,ITEM DESCRIPTION,,,, 20 | item_contribution_aquired_date,18,ITEM CONTRIBUTION/AQUIRED DATE ,13,DATE (Of Contribution),13,DATE (Of Contribution) 21 | item_fair_market_value,19,ITEM FAIR MARKET VALUE,14,FAIR MARKET VALUE OF ITEM,14,FAIR MARKET VALUE OF ITEM 22 | contributor_employer,20,CONTRIBUTOR EMPLOYER,11,INDEMP,11,INDEMP 23 | contributor_occupation,21,CONTRIBUTOR OCCUPATION,12,INDOCC ,12,INDOCC 24 | memo_code,22,MEMO CODE,29,MEMO CODE,29,MEMO CODE 25 | memo_text_description,23,MEMO TEXT/DESCRIPTION,30,MEMO TEXT,30,MEMO TEXT 26 | transaction_code,,,15,TRANSACTION CODE,15,TRANSACTION CODE 27 | transaction_description,,,16,TRANSDESC,16,TRANSDESC 28 | fec_committee_id_number,,,17,FEC COMMITTEE ID NUMBER,17,FEC COMMITTEE ID NUMBER 29 | fec_candidate_id_number,,,18,FEC CANDIDATE ID NUMBER,18,FEC CANDIDATE ID NUMBER 30 | candidate_name,,,19,CANDIDATE NAME,19,CANDIDATE NAME 31 | candidate_office,,,20,CAN/OFFICE,20,CAN/OFFICE 32 | candidate_state,,,21,CAN/STATE ,21,CAN/STATE 33 | candidate_district,,,22,CAN/DIST,22,CAN/DIST 34 | conduit_name,,,23,CONDUIT NAME,23,CONDUIT NAME 35 | conduit_street_1,,,24,CONDUIT STREET 1,24,CONDUIT STREET 1 36 | conduit_street_2,,,25,CONDUIT STREET 2,25,CONDUIT STREET 2 37 | conduit_city,,,26,CONDUIT CITY,26,CONDUIT CITY 38 | conduit_state,,,27,CONDUIT STATE,27,CONDUIT STATE 39 | conduit_zip,,,28,CONDUIT ZIP,28,CONDUIT ZIP 40 | -------------------------------------------------------------------------------- /spec/sources/SchA.csv: -------------------------------------------------------------------------------- 1 | canonical,^7.0|6.4,,^6.3|6.2,,^6.1,,^5.3,,^5.2,,^5.1,,^5.0,,^3, form_type,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE filer_committee_id_number,2,FILER COMMITTEE ID NUMBER,2,FILER COMMITTEE ID NUMBER,2,FILER COMMITTEE ID NUMBER,2,FILER FEC CMTE ID,2,FILER FEC CMTE ID,2,FILER FEC CMTE ID,2,FILER FEC CMTE ID,2,FILER FEC CMTE ID transaction_id,3,TRANSACTION ID ,3,TRANSACTION ID ,3,TRANSACTION ID ,34,TRAN ID,34,TRAN ID,34,TRAN ID,34,TRAN ID,34,TRAN ID back_reference_tran_id_number,4,BACK REFERENCE TRAN ID NUMBER,4,BACK REFERENCE TRAN ID NUMBER,4,BACK REFERENCE TRAN ID NUMBER,35,BACK REF TRAN ID,35,BACK REF TRAN ID,35,BACK REF TRAN ID,35,BACK REF TRAN ID,35,BACK REF TRAN ID back_reference_sched_name,5,BACK REFERENCE SCHED NAME,5,BACK REFERENCE SCHED NAME,5,BACK REFERENCE SCHED NAME,36,BACK REF SCHED NAME,36,BACK REF SCHED NAME,36,BACK REF SCHED NAME,36,BACK REF SCHED NAME,36,BACK REF SCHED NAME entity_type,6,ENTITY TYPE,6,ENTITY TYPE,6,ENTITY TYPE,3,ENTITY TYPE,3,ENTITY TYPE,3,ENTITY TYPE,3,ENTITY TYPE,3,ENTITY TYPE contributor_name,,,,,,,4,CONTRIBUTOR NAME,4,CONTRIBUTOR NAME,4,CONTRIBUTOR NAME,4,CONTRIBUTOR NAME,4, CONTRIBUTOR NAME contributor_organization_name,7,CONTRIBUTOR ORGANIZATION NAME,7,CONTRIBUTOR ORGANIZATION NAME,7,CONTRIBUTOR ORGANIZATION NAME,39,CONTRIB ORGANIZATION NAME,39,CONTRIB ORGANIZATION NAME,39,CONTRIB ORGANIZATION NAME,,,, contributor_last_name,8,CONTRIBUTOR LAST NAME,8,CONTRIBUTOR LAST NAME,8,CONTRIBUTOR LAST NAME,40,CONTRIBUTOR LAST NAME,40,CONTRIBUTOR LAST NAME,40,CONTRIBUTOR LAST NAME,,,, contributor_first_name,9,CONTRIBUTOR FIRST NAME,9,CONTRIBUTOR FIRST NAME,9,CONTRIBUTOR FIRST NAME,41,CONTRIBUTOR FIRST NAME,41,CONTRIBUTOR FIRST NAME,41,CONTRIBUTOR FIRST NAME,,,, contributor_middle_name,10,CONTRIBUTOR MIDDLE NAME,10,CONTRIBUTOR MIDDLE NAME,10,CONTRIBUTOR MIDDLE NAME,42,CONTRIBUTOR MIDDLE NAME,42,CONTRIBUTOR MIDDLE NAME,42,CONTRIBUTOR MIDDLE NAME,,,, contributor_prefix,11,CONTRIBUTOR PREFIX,11,CONTRIBUTOR PREFIX,11,CONTRIBUTOR PREFIX,43,CONTRIBUTOR PREFIX,43,CONTRIBUTOR PREFIX,43,CONTRIBUTOR PREFIX,,,, contributor_suffix,12,CONTRIBUTOR SUFFIX,12,CONTRIBUTOR SUFFIX,12,CONTRIBUTOR SUFFIX,44,CONTRIBUTOR SUFFIX,44,CONTRIBUTOR SUFFIX,44,CONTRIBUTOR SUFFIX,,,, contributor_street_1,13,CONTRIBUTOR STREET 1,13,CONTRIBUTOR STREET 1,13,CONTRIBUTOR STREET 1,5,STREET 1,5,STREET 1,5,STREET 1,5,STREET 1,5,STREET 1 contributor_street_2,14,CONTRIBUTOR STREET 2,14,CONTRIBUTOR STREET 2,14,CONTRIBUTOR STREET 2,6,STREET 2,6,STREET 2,6,STREET 2,6,STREET 2,6,STREET 2 contributor_city,15,CONTRIBUTOR CITY,15,CONTRIBUTOR CITY,15,CONTRIBUTOR CITY,7,CITY,7,CITY,7,CITY,7,CITY,7,CITY contributor_state,16,CONTRIBUTOR STATE,16,CONTRIBUTOR STATE,16,CONTRIBUTOR STATE,8,STATE,8,STATE,8,STATE,8,STATE,8,STATE contributor_zip,17,CONTRIBUTOR ZIP,17,CONTRIBUTOR ZIP,17,CONTRIBUTOR ZIP,9,ZIP,9,ZIP,9,ZIP,9,ZIP,9,ZIP election_code,18,ELECTION CODE,18,ELECTION CODE,18,ELECTION CODE,10,ITEM ELECT CD,10,ITEM ELECT CD,10,ITEM ELECT CD,10,ITEM ELECT CD,10,ITEM ELECT CD election_other_description,19,ELECTION OTHER DESCRIPTION ,19,ELECTION OTHER DESCRIPTION ,19,ELECTION OTHER DESCRIPTION ,11,ITEM ELECT OTHER,11,ITEM ELECT OTHER,11,ITEM ELECT OTHER,11,ITEM ELECT OTHER,11,ITEM ELECT OTHER contribution_date,20,CONTRIBUTION DATE,20,CONTRIBUTION DATE,20,CONTRIBUTION DATE,15,DATE RECEIVED,15,DATE RECEIVED,15,DATE RECEIVED,15,DATE RECEIVED,15,DATE RECEIVED contribution_amount,21,CONTRIBUTION AMOUNT {F3L Bundled},21,CONTRIBUTION AMOUNT,21,CONTRIBUTION AMOUNT,16,AMOUNT RECEIVED,16,AMOUNT RECEIVED,16,AMOUNT RECEIVED,16,AMOUNT RECEIVED,16,AMOUNT RECEIVED contribution_aggregate,22,CONTRIBUTION AGGREGATE {F3L Semi-annual Bundled},22,CONTRIBUTION AGGREGATE,22,CONTRIBUTION AGGREGATE,14,AGGREGATE AMT TO DATE,14,AGGREGATE AMT TO DATE,14,AGGREGATE AMT Y-T-D,14,AGGREGATE AMT Y-T-D,14,AGGREGATE AMT Y-T-D contribution_purpose_code,23,CONTRIBUTION PURPOSE CODE,23,CONTRIBUTION PURPOSE CODE,23,CONTRIBUTION PURPOSE CODE,17,TRANS CODE,17,TRANS CODE,17,TRANS CODE,17,TRANS CODE,17,TRANS CODE contribution_purpose_descrip,24,CONTRIBUTION PURPOSE DESCRIP,24,CONTRIBUTION PURPOSE DESCRIP,24,CONTRIBUTION PURPOSE DESCRIP,18,TRANS DESCRIP,18,TRANS DESCRIP,18,TRANS DESCRIP,18,TRANS DESCRIP,18,TRANS DESCRIP increased_limit_code,,,25,INCREASED LIMIT CODE,25,INCREASED LIMIT CODE,38,INCREASED LIMIT,38,INCREASED LIMIT,38,INCREASED LIMIT,38,INCREASED LIMIT,, contributor_employer,25,CONTRIBUTOR EMPLOYER,26,CONTRIBUTOR EMPLOYER,26,CONTRIBUTOR EMPLOYER,12,INDEMP,12,INDEMP,12,INDEMP,12,INDEMP,12,INDEMP contributor_occupation,26,CONTRIBUTOR OCCUPATION,27,CONTRIBUTOR OCCUPATION,27,CONTRIBUTOR OCCUPATION,13,INDOCC,13,INDOCC,13,INDOCC,13,INDOCC,13,INDOCC donor_committee_fec_id,27,DONOR COMMITTEE FEC ID,28,DONOR COMMITTEE FEC ID,28,DONOR COMMITTEE FEC ID,19,FEC COMMITTEE ID NUMBER,19,FEC COMMITTEE ID NUMBER,19,FEC COMMITTEE ID NUMBER,19,FEC COMMITTEE ID NUMBER,19,FEC COMMITTEE ID NUMBER donor_committee_name,28,DONOR COMMITTEE NAME,29,DONOR COMMITTEE NAME,,,,,,,,,,,, donor_candidate_fec_id,29,DONOR CANDIDATE FEC ID,30,DONOR CANDIDATE FEC ID,29,DONOR CANDIDATE FEC ID,20,FEC CANDIDATE ID NUMBER,20,FEC CANDIDATE ID NUMBER,20,FEC CANDIDATE ID NUMBER,20,FEC CANDIDATE ID NUMBER,20,FEC CANDIDATE ID NUMBER donor_candidate_name,,,,,,,21,CANDIDATE NAME,21,CANDIDATE NAME,21,CANDIDATE NAME,21,CANDIDATE NAME,21,CANDIDATE NAME donor_candidate_last_name,30,DONOR CANDIDATE LAST NAME,31,DONOR CANDIDATE LAST NAME,30,DONOR CANDIDATE LAST NAME,,,,,,,,,, donor_candidate_first_name,31,DONOR CANDIDATE FIRST NAME,32,DONOR CANDIDATE FIRST NAME,31,DONOR CANDIDATE FIRST NAME,,,,,,,,,, donor_candidate_middle_name,32,DONOR CANDIDATE MIDDLE NAME,33,DONOR CANDIDATE MIDDLE NAME,32,DONOR CANDIDATE MIDDLE NAME,,,,,,,,,, donor_candidate_prefix,33,DONOR CANDIDATE PREFIX,34,DONOR CANDIDATE PREFIX,33,DONOR CANDIDATE PREFIX,,,,,,,,,, donor_candidate_suffix,34,DONOR CANDIDATE SUFFIX,35,DONOR CANDIDATE SUFFIX,34,DONOR CANDIDATE SUFFIX,,,,,,,,,, donor_candidate_office,35,DONOR CANDIDATE OFFICE,36,DONOR CANDIDATE OFFICE,35,DONOR CANDIDATE OFFICE,22,CAN/OFFICE,22,CAN/OFFICE,22,CAN/OFFICE,22,CAN/OFFICE,22,CAN/OFFICE donor_candidate_state,36,DONOR CANDIDATE STATE ,37,DONOR CANDIDATE STATE ,36,DONOR CANDIDATE STATE ,23,CAN/STATE ,23,CAN/STATE ,23,CAN/STATE ,23,CAN/STATE ,23,CAN/STATE donor_candidate_district,37,DONOR CANDIDATE DISTRICT,38,DONOR CANDIDATE DISTRICT,37,DONOR CANDIDATE DISTRICT,24,CAN/DIST,24,CAN/DIST,24,CAN/DIST,24,CAN/DIST,24,CAN/DIST conduit_name,38,CONDUIT NAME,39,CONDUIT NAME,38,CONDUIT NAME,25,CONDUIT NAME,25,CONDUIT NAME,25,CONDUIT NAME,25,CONDUIT NAME,25,CONDUIT NAME conduit_street1,39,CONDUIT STREET1,40,CONDUIT STREET1,39,CONDUIT STREET1,26,CONDUIT STREET1,26,CONDUIT STREET1,26,CONDUIT STREET1,26,CONDUIT STREET1,26,CONDUIT STREET1 conduit_street2,40,CONDUIT STREET2,41,CONDUIT STREET2,40,CONDUIT STREET2,27,CONDUIT STREET2,27,CONDUIT STREET2,27,CONDUIT STREET2,27,CONDUIT STREET2,27,CONDUIT STREET2 conduit_city,41,CONDUIT CITY,42,CONDUIT CITY,41,CONDUIT CITY,28,CONDUIT CITY,28,CONDUIT CITY,28,CONDUIT CITY,28,CONDUIT CITY,28,CONDUIT CITY conduit_state,42,CONDUIT STATE,43,CONDUIT STATE,42,CONDUIT STATE,29,CONDUIT STATE,29,CONDUIT STATE,29,CONDUIT STATE,29,CONDUIT STATE,29,CONDUIT STATE conduit_zip,43,CONDUIT ZIP,44,CONDUIT ZIP,43,CONDUIT ZIP,30,CONDUIT ZIP,30,CONDUIT ZIP,30,CONDUIT ZIP,30,CONDUIT ZIP,30,CONDUIT ZIP memo_code,44,MEMO CODE,45,MEMO CODE,44,MEMO CODE,31,MEMO CODE,31,MEMO CODE,31,MEMO CODE,31,MEMO CODE,31,MEMO CODE memo_text_description,45,MEMO TEXT/DESCRIPTION,46,MEMO TEXT/DESCRIPTION,45,MEMO TEXT/DESCRIPTION,32,MEMO TEXT,32,MEMO TEXT,32,MEMO TEXT,32,MEMO TEXT,32,MEMO TEXT reference_code,46,Reference to SI or SL system code that identifies the Account,47,Reference to SI or SL system code that identifies the Account,46,Reference to SI or SL system code that identifies the Account,37,Reference to SI or SL system code that identifies the Account,37,Reference to SI or SL system code that identifies the Account,37,Reference to SI or SL system code that identifies the Account,37,Reference to SI or SL system code that identifies the Account,37,NAT CMTTE NON-FED ACCT -------------------------------------------------------------------------------- /spec/sources/SchB.csv: -------------------------------------------------------------------------------- 1 | canonical,^7.0|6.4,,^6.3|6.2,,^6.1,,^5.3,,^5.2|5.1,,^5.0,,^3, form_type,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE filer_committee_id_number,2,FILER COMMITTEE ID NUMBER,2,FILER COMMITTEE ID NUMBER,2,FILER COMMITTEE ID NUMBER,2,FILER FEC CMTE ID,2,FILER FEC CMTE ID,2,FILER FEC CMTE ID,2,FILER FEC CMTE ID transaction_id_number,3,TRANSACTION ID NUMBER,3,TRANSACTION ID NUMBER,3,TRANSACTION ID NUMBER,31,TRAN ID,31,TRAN ID,31,TRAN ID,31,TRAN ID back_reference_tran_id_number,4,BACK REFERENCE TRAN ID NUMBER,4,BACK REFERENCE TRAN ID NUMBER,4,BACK REFERENCE TRAN ID NUMBER,32,BACK REF TRAN ID,32,BACK REF TRAN ID,32,BACK REF TRAN ID,32,BACK REF TRAN ID back_reference_sched_name,5,BACK REFERENCE SCHED NAME,5,BACK REFERENCE SCHED NAME,5,BACK REFERENCE SCHED NAME,33,BACK REF SCHED NAME,33,BACK REF SCHED NAME,33,BACK REF SCHED NAME,33,BACK REF SCHED NAME entity_type,6,ENTITY TYPE,6,ENTITY TYPE,6,ENTITY TYPE,3,ENTITY TYPE,3,ENTITY TYPE,3,ENTITY TYPE,3,ENTITY TYPE payee_name,,,,,,,4,RECIPIENT NAME,4,RECIPIENT NAME,4,RECIPIENT NAME,4,RECIPIENT NAME payee_organization_name,7,PAYEE ORGANIZATION NAME,7,PAYEE ORGANIZATION NAME,7,PAYEE ORGANIZATION NAME,38,RECIPIENT ORGANIZATION NAME,38,RECIPIENT ORGANIZATION NAME,,,, payee_last_name,8,PAYEE LAST NAME,8,PAYEE LAST NAME,8,PAYEE LAST NAME,39,RECIPIENT LAST NAME,39,RECIPIENT LAST NAME,,,, payee_first_name,9,PAYEE FIRST NAME,9,PAYEE FIRST NAME,9,PAYEE FIRST NAME,40,RECIPIENT FIRST NAME,40,RECIPIENT FIRST NAME,,,, payee_middle_name,10,PAYEE MIDDLE NAME,10,PAYEE MIDDLE NAME,10,PAYEE MIDDLE NAME,41,RECIPIENT MIDDLE NAME,41,RECIPIENT MIDDLE NAME,,,, payee_prefix,11,PAYEE PREFIX,11,PAYEE PREFIX,11,PAYEE PREFIX,42,RECIPIENT PREFIX,42,RECIPIENT PREFIX,,,, payee_suffix,12,PAYEE SUFFIX,12,PAYEE SUFFIX,12,PAYEE SUFFIX,43,RECIPIENT SUFFIX,43,RECIPIENT SUFFIX,,,, payee_street_1,13,PAYEE STREET 1,13,PAYEE STREET 1,13,PAYEE STREET 1,5,STREET 1,5,STREET 1,5,STREET 1,5,STREET 1 payee_street_2,14,PAYEE STREET 2,14,PAYEE STREET 2,14,PAYEE STREET 2,6,STREET 2,6,STREET 2,6,STREET 2,6,STREET 2 payee_city,15,PAYEE CITY,15,PAYEE CITY,15,PAYEE CITY,7,CITY,7,CITY,7,CITY,7,CITY payee_state,16,PAYEE STATE,16,PAYEE STATE,16,PAYEE STATE,8,STATE,8,STATE,8,STATE,8,STATE payee_zip,17,PAYEE ZIP,17,PAYEE ZIP,17,PAYEE ZIP,9,ZIP,9,ZIP,9,ZIP,9,ZIP election_code,18,ELECTION CODE,18,ELECTION CODE,18,ELECTION CODE,12,ITEM ELECT CD,12,ITEM ELECT CD,12,ITEM ELECT CD,12,ITEM ELECT CD election_other_description,19,ELECTION OTHER DESCRIPTION ,19,ELECTION OTHER DESCRIPTION ,19,ELECTION OTHER DESCRIPTION ,13,ITEM ELECT OTHER,13,ITEM ELECT OTHER,13,ITEM ELECT OTHER,13,ITEM ELECT OTHER expenditure_date,20,EXPENDITURE DATE,20,EXPENDITURE DATE,20,EXPENDITURE DATE,14,DATE OF EXPENDITURE,14,DATE OF EXPENDITURE,14,DATE OF EXPENDITURE,14,DATE OF EXPENDITURE expenditure_amount,21,EXPENDITURE AMOUNT {F3L Bundled},21,EXPENDITURE AMOUNT,21,EXPENDITURE AMOUNT,15,AMOUNT OF EXPENDITURE,15,AMOUNT OF EXPENDITURE,15,AMOUNT OF EXPENDITURE,15,AMOUNT OF EXPENDITURE semi_annual_refunded_bundled_amt,22,SEMI-ANNUAL REFUNDED BUNDLED AMT,,,,,,,,,,,, expenditure_purpose_code,23,EXPENDITURE PURPOSE CODE,22,EXPENDITURE PURPOSE CODE,22,EXPENDITURE PURPOSE CODE,10,TRANS {Purpose} CODE,10,TRANS {Purpose} CODE,10,TRANS {Purpose} CODE,10,TRANS CODE expenditure_purpose_descrip,24,EXPENDITURE PURPOSE DESCRIP,23,EXPENDITURE PURPOSE DESCRIP,23,EXPENDITURE PURPOSE DESCRIP,11,TRANS {Purpose} DESCRIP,11,TRANS {Purpose} DESCRIP,11,TRANS {Purpose} DESCRIP,11,TRANS DESCRIP category_code,25,CATEGORY CODE,24,CATEGORY CODE,24,CATEGORY CODE,36,CATEGORY CODE,36,CATEGORY CODE,36,CATEGORY CODE,, beneficiary_committee_fec_id,26,BENEFICIARY COMMITTEE FEC ID,27,BENEFICIARY COMMITTEE FEC ID,27,PAYEE COMMITTEE FEC ID,16,FEC COMMITTEE ID NUMBER,16,FEC COMMITTEE ID NUMBER,16,FEC COMMITTEE ID NUMBER,16,FEC COMMITTEE ID NUMBER beneficiary_committee_name,27,BENEFICIARY COMMITTEE NAME,28,BENEFICIARY COMMITTEE NAME,,,,,,,,,, beneficiary_candidate_fec_id,28,BENEFICIARY CANDIDATE FEC ID,29,BENEFICIARY CANDIDATE FEC ID,28,PAYEE CANDIDATE FEC ID,17,FEC CANDIDATE ID NUMBER,17,FEC CANDIDATE ID NUMBER,17,FEC CANDIDATE ID NUMBER,17,FEC CANDIDATE ID NUMBER beneficiary_candidate_name,,,,,,,18,CANDIDATE NAME,18,CANDIDATE NAME,18,CANDIDATE NAME,18,CANDIDATE NAME beneficiary_candidate_last_name,29,BENEFICIARY CANDIDATE LAST NAME,30,BENEFICIARY CANDIDATE LAST NAME,29,PAYEE CANDIDATE LAST NAME,,,,,,,, beneficiary_candidate_first_name,30,BENEFICIARY CANDIDATE FIRST NAME,31,BENEFICIARY CANDIDATE FIRST NAME,30,PAYEE CANDIDATE FIRST NAME,,,,,,,, beneficiary_candidate_middle_name,31,BENEFICIARY CANDIDATE MIDDLE NAME,32,BENEFICIARY CANDIDATE MIDDLE NAME,31,PAYEE CANDIDATE MIDDLE NAME,,,,,,,, beneficiary_candidate_prefix,32,BENEFICIARY CANDIDATE PREFIX,33,BENEFICIARY CANDIDATE PREFIX,32,PAYEE CANDIDATE PREFIX,,,,,,,, beneficiary_candidate_suffix,33,BENEFICIARY CANDIDATE SUFFIX,34,BENEFICIARY CANDIDATE SUFFIX,33,PAYEE CANDIDATE SUFFIX,,,,,,,, beneficiary_candidate_office,34,BENEFICIARY CANDIDATE OFFICE,35,BENEFICIARY CANDIDATE OFFICE,34,PAYEE CANDIDATE OFFICE,19,CAN/OFFICE,19,CAN/OFFICE,19,CAN/OFFICE,19,CAN/OFFICE beneficiary_candidate_state,35,BENEFICIARY CANDIDATE STATE ,36,BENEFICIARY CANDIDATE STATE ,35,PAYEE CANDIDATE STATE ,20,CAN/STATE ,20,CAN/STATE ,20,CAN/STATE ,20,CAN/STATE beneficiary_candidate_district,36,BENEFICIARY CANDIDATE DISTRICT,37,BENEFICIARY CANDIDATE DISTRICT,36,PAYEE CANDIDATE DISTRICT,21,CAN/DIST,21,CAN/DIST,21,CAN/DIST,21,CAN/DIST conduit_name,37,CONDUIT NAME,38,CONDUIT NAME,37,CONDUIT NAME,22,CONDUIT NAME,22,CONDUIT NAME,22,CONDUIT NAME,22,CONDUIT NAME conduit_street_1,38,CONDUIT STREET 1,39,CONDUIT STREET 1,38,CONDUIT STREET 1,23,CONDUIT STREET 1,23,CONDUIT STREET 1,23,CONDUIT STREET 1,23,CONDUIT STREET 1 conduit_street_2,39,CONDUIT STREET 2,40,CONDUIT STREET 2,39,CONDUIT STREET 2,24,CONDUIT STREET 2,24,CONDUIT STREET 2,24,CONDUIT STREET 2,24,CONDUIT STREET 2 conduit_city,40,CONDUIT CITY,41,CONDUIT CITY,40,CONDUIT CITY,25,CONDUIT CITY,25,CONDUIT CITY,25,CONDUIT CITY,25,CONDUIT CITY conduit_state,41,CONDUIT STATE,42,CONDUIT STATE,41,CONDUIT STATE,26,CONDUIT STATE,26,CONDUIT STATE,26,CONDUIT STATE,26,CONDUIT STATE conduit_zip,42,CONDUIT ZIP,43,CONDUIT ZIP,42,CONDUIT ZIP,27,CONDUIT ZIP,27,CONDUIT ZIP,27,CONDUIT ZIP,27,CONDUIT ZIP memo_code,43,MEMO CODE,44,MEMO CODE,43,MEMO CODE,28,MEMO CODE,28,MEMO CODE,28,MEMO CODE,28,MEMO CODE memo_text_description,44,MEMO TEXT/DESCRIPTION,45,MEMO TEXT/DESCRIPTION,44,MEMO TEXT/DESCRIPTION,29,MEMO TEXT,29,MEMO TEXT,29,MEMO TEXT,29,MEMO TEXT reference_to_si_or_sl_system_code_that_identifies_the_account,45,Reference to SI or SL system code that identifies the Account,46,Reference to SI or SL system code that identifies the Account,45,Reference to SI or SL system code that identifies the Account,34,Reference to SI or SL system code that identifies the Account,34,Reference to SI or SL system code that identifies the Account,34,Reference to SI or SL system code that identifies the Account,34,NAT CMTTE NON-FED ACCT refund_or_disposal_of_excess,,,25,REFUND OR DISPOSAL OF EXCESS ,25,REFUND OR DISPOSAL OF EXCESS ,35,REFUND OR DISPOSAL OF EXCESS ,35,REFUND OR DISPOSAL OF EXCESS ,35,REFUND OR DISPOSAL OF EXCESS ,, communication_date,,,26,COMMUNICATION DATE,26,COMMUNICATION DATE,37,COMMUNICATION DATE,37,COMMUNICATION DATE,37,COMMUNICATION DATE,, -------------------------------------------------------------------------------- /spec/sources/SchC.csv: -------------------------------------------------------------------------------- 1 | canonical,^7.0|6.4|6.3|6.2,,^6.1,,^5.3,,^5.2|5.1,,^5.0|3, form_type,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE filer_committee_id_number,2,FILER COMMITTEE ID NUMBER,2,FILER COMMITTEE ID NUMBER,2,FILER FEC CMTE ID,2,FILER FEC CMTE ID,2,FILER FEC CMTE ID transaction_id_number,3,TRANSACTION ID NUMBER,3,TRANSACTION ID NUMBER,26,TRAN ID,26,TRAN ID,26,TRAN ID receipt_line_number,4,RECEIPT LINE NUMBER,4,RECEIPT LINE NUMBER,27,RECEIPT LINE NUMBER,27,RECEIPT LINE NUMBER,, entity_type,5,ENTITY TYPE,5,ENTITY TYPE,3, ENTITY TYPE,3, ENTITY TYPE,3, ENTITY TYPE lender_name,,,,,4,NAME (Loan Source),4,NAME (Loan Source),4,NAME (Loan Source) lender_organization_name,6,LENDER ORGANIZATION NAME,6,LENDER ORGANIZATION NAME,,,,,, lender_last_name,7,LENDER LAST NAME,7,LENDER LAST NAME,,,,,, lender_first_name,8,LENDER FIRST NAME,8,LENDER FIRST NAME,,,,,, lender_middle_name,9,LENDER MIDDLE NAME,9,LENDER MIDDLE NAME,,,,,, lender_prefix,10,LENDER PREFIX,10,LENDER PREFIX,,,,,, lender_suffix,11,LENDER SUFFIX,11,LENDER SUFFIX,,,,,, lender_street_1,12,LENDER STREET 1,12,LENDER STREET 1,5,STREET 1,5,STREET 1,5,STREET 1 lender_street_2,13,LENDER STREET 2,13,LENDER STREET 2,6,STREET 2,6,STREET 2,6,STREET 2 lender_city,14,LENDER CITY,14,LENDER CITY,7,CITY,7,CITY,7,CITY lender_state,15,LENDER STATE,15,LENDER STATE,8,STATE,8,STATE,8,STATE lender_zip,16,LENDER ZIP,16,LENDER ZIP,9,ZIP,9,ZIP,9,ZIP election_code,17,ELECTION CODE,17,ELECTION CODE,10,ELECTION ,10,ELECTION ,10,ELECTION election_other_description,18,ELECTION OTHER DESCRIPTION ,18,ELECTION OTHER DESCRIPTION ,11,ELECTION DESCRIPTION,11,ELECTION DESCRIPTION,11,ELECTION DESCRIPTION loan_amount_original,19,LOAN AMOUNT (Original),19,LOAN AMOUNT (Original),12,ORIG. AMT OF LOAN,12,ORIG. AMT OF LOAN,12,ORIG. AMT OF LOAN loan_payment_to_date,20,LOAN PAYMENT TO DATE,20,LOAN PAYMENT TO DATE,13,PAYMENT TO DATE,13,PAYMENT TO DATE,13,PAYMENT TO DATE loan_balance,21,LOAN BALANCE,21,LOAN BALANCE,14,LOAN BALANCE,14,LOAN BALANCE,14,LOAN BALANCE loan_incurred_date_terms,22,LOAN INCURRED DATE (Terms),22,LOAN INCURRED DATE (Terms),15,DATE (Incurred),15,DATE (Incurred),15,DATE (Incurred) loan_due_date_terms,23,LOAN DUE DATE (Terms),23,LOAN DUE DATE (Terms),16,DUE DATE TERMS,16,DUE DATE TERMS,16,DUE DATE TERMS loan_interest_rate_terms,24,LOAN INTEREST RATE % (Terms),24,LOAN INTEREST RATE % (Terms),17,PCT RATE TERMS,17,PCT RATE TERMS,17,PCT RATE TERMS secured,25,YES/NO (Secured?),25,YES/NO (Secured?),18,SECURED YESNO,18,SECURED YESNO,18,SECURED YESNO personal_funds,26,YES/NO (Personal Funds),,,,,,,, lender_committee_id_number,27,LENDER COMMITTEE ID NUMBER,26,LENDER COMMITTEE ID NUMBER,19,FEC COMMITTEE ID NUMBER,19,FEC COMMITTEE ID NUMBER,19,FEC COMMITTEE ID NUMBER lender_candidate_id_number,28,LENDER CANDIDATE ID NUMBER,27,LENDER CANDIDATE ID NUMBER,20,FEC CANDIDATE ID NUMBER,20,FEC CANDIDATE ID NUMBER,20,FEC CANDIDATE ID NUMBER lender_candidate_name,,,,,21,CANDIDATE NAME,21,CANDIDATE NAME,21,CANDIDATE NAME lender_candidate_last_name,29,LENDER CANDIDATE LAST NAME,28,LENDER CANDIDATE LAST NAME,,,,,, lender_candidate_first_name,30,LENDER CANDIDATE FIRST NAME,29,LENDER CANDIDATE FIRST NAME,,,,,, lender_candidate_middle_nm,31,LENDER CANDIDATE MIDDLE NM,30,LENDER CANDIDATE MIDDLE NM,,,,,, lender_candidate_prefix,32,LENDER CANDIDATE PREFIX,31,LENDER CANDIDATE PREFIX,,,,,, lender_candidate_suffix,33,LENDER CANDIDATE SUFFIX,32,LENDER CANDIDATE SUFFIX,,,,,, lender_candidate_office,34,LENDER CANDIDATE OFFICE,33,LENDER CANDIDATE OFFICE,22,CAN/OFFICE,22,CAN/OFFICE,22,CAN/OFFICE lender_candidate_state,35,LENDER CANDIDATE STATE ,34,LENDER CANDIDATE STATE ,23,CAN/STATE ,23,CAN/STATE ,23,CAN/STATE lender_candidate_district,36,LENDER CANDIDATE DISTRICT,35,LENDER CANDIDATE DISTRICT,24,CAN/DIST,24,CAN/DIST,24,CAN/DIST memo_code,37,MEMO CODE,,,,,,,, memo_text_description,38,MEMO TEXT/DESCRIPTION,,,,,,,, -------------------------------------------------------------------------------- /spec/sources/headers/3.csv: -------------------------------------------------------------------------------- 1 | Header,Record Type,EF Type,FEC Ver,Soft Name,Soft Ver,Name Delim,Rpt ID,Rpt Number,HDRcomment ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F1,FORM TYPE,FILER FEC CMTE ID ,COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,DATE (Submitted),CHG OF COMMITTEE NAME,CHG OF ADDRESS,5. COMMITTEE TYPE,5. FEC CANDIDATE ID NUMBER,5. CANDIDATE NAME,5. CAN/OFFICE ,5. CAN/STATE,5. CAN/DIST,5. PARTY CODE,5. PARTY TYPE,6. FEC COMMITTEE ID NUMBER,6. COMMITTEE NAME (Affiliated),6. STREET 1,6. STREET 2,6. CITY,6. STATE,6. ZIP,6. RELATIONSHIP (w/ Above Cmte),6. ORGANIZATION TYPE,7. IND/NAME (Custodian Name),7. STREET 1,7. STREET 2,7. CITY,7. STATE,7. ZIP,7. TITLE,7. TELEPHONE,8. IND/NAME (Treasurer),8. STREET 1,8. STREET 2,8. CITY,8. STATE,8. ZIP,8. TITLE,8. TELEPHONE,8. IND/NAME (Designated Agent),8. STREET 1,8. STREET 2,8. CITY,8. STATE,8. ZIP,8. TITLE,8. TELEPHONE,9. IND/NAME (Bank/Depository),9. STREET 1,9. STREET 2,9. CITY,9. STATE,9. ZIP,NAME/TREASURER (as signed),DATE (Signed),,COMMITTEE EMAIL,COMMITTEE WEB URL,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F1S,FORM TYPE,FILER FEC CMTE ID ,COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,DATE (Submitted),CHG OF COMMITTEE NAME,CHG OF ADDRESS,5. COMMITTEE TYPE,5. FEC CANDIDATE ID NUMBER,5. CANDIDATE NAME,5. CAN/OFFICE ,5. CAN/STATE,5. CAN/DIST,5. PARTY CODE,5. PARTY TYPE,6. FEC COMMITTEE ID NUMBER,6. COMMITTEE NAME (Affiliated),6. STREET 1,6. STREET 2,6. CITY,6. STATE,6. ZIP,6. RELATIONSHIP (w/ Above Cmte),6. ORGANIZATION TYPE,7. IND/NAME (Custodian Name),7. STREET 1,7. STREET 2,7. CITY,7. STATE,7. ZIP,7. TITLE,7. TELEPHONE,8. IND/NAME (Treasurer),8. STREET 1,8. STREET 2,8. CITY,8. STATE,8. ZIP,8. TITLE,8. TELEPHONE,8. IND/NAME (Designated Agent),8. STREET 1,8. STREET 2,8. CITY,8. STATE,8. ZIP,8. TITLE,8. TELEPHONE,9. IND/NAME (Bank/Depository),9. STREET 1,9. STREET 2,9. CITY,9. STATE,9. ZIP,NAME/TREASURER (as signed),DATE (Signed),COMMITTEE EMAIL,COMMITTEE WEB URL,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F1M,FORM TYPE ,FILER FEC CMTE ID ,COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,COMMITTEE TYPE,DATE (Of Affiliation),FEC COMMITTEE ID NUMBER,COMMITTEE NAME,FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE ,CAN/DIST, DATE (Of Contribution),FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE ,CAN/DIST,DATE (Of Contribution),FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE ,CAN/DIST,DATE (Of Contribution),FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE ,CAN/DIST,DATE (Of Contribution),FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE ,CAN/DIST,DATE (Of Contribution),DATE (Of 51st Contributor),DATE (Of Orig Registration),DATE (Cmte Met Requirements),NAME/TREASURER (as signed),DATE (Signed),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F2,FORM TYPE,FILER FEC CAND ID ,CANDIDATE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,PTY/CODE,CAN/OFFICE,CAN/STATE ,CAN/DIST,YEAR OF ELECTION 1900-2999,FEC COMMITTEE ID NUMBER (PCC),COMMITTEE NAME (PCC),STREET 1,STREET 2,CITY,STATE,ZIP,FEC COMMITTEE ID NUMBER (Auth),COMMITTEE NAME (Auth),STREET 1,STREET 2,CITY,STATE,ZIP,NAME/CAN (as signed),DATE (Signed),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F24,FORM TYPE,FILER FEC CMTE ID,COMMITTEE NAME ,STREET 1,STREET 2,CITY,STATE,ZIP,NAME/TREASURER (as signed),DATE (Signed),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F3,FORM TYPE,FILER FEC CMTE ID,COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,CHG OF ADDRESS,ELECTION STATE,ELECTION DISTRICT,RPTCODE,RPTPGI,DATE (Of Election),STATE (Of Election),PRIMARY ELECTION ,GENERAL ELECTION,SPECIAL ELECTION ,RUNOFF ELECTION ,DATE (Coverage From),DATE (Coverage To),(6a) Total Contributions (NO Loans),(6b) Total Contribution Refunds,(6c) Net Contributions,(7a) Total Operating Expenditures,(7b) Total Offset to Operating Expenditures,(7c) NET Operating Expenditures.,8. CASH ON HAND AT CLOSE ...,9. DEBTS TO ( Totals from SCH C and/or D),10. DEBTS BY (Totals from SCH C and/or D),11(a i.) Individuals Itemized,11(a.ii) Individuals Unitemized,11(a.iii) Individual Contribution Total,11(b) Political Party Committees,11(c) Other Political Committees,11(d) The Candidate,11(e) Total Contributions,12. Transfers From Other Authorized Cmttes,13(a) Loans made or guarn. by the Candidate,13(b) All Other Loans,13(c) Total Loans,14. Offsets to Operating Expenditures,15. Other Receipts,16. Total Receipts,17. Operating Expenditures,18. Transfers to Other Authorized Committees,19(a) Of Loans made or guar. by the Cand.,"19(b) Loan Repayments, All Other Loans",19(c) Total Loan Repayments,20(a) Refund/Individuals Other than Pol. Cmtes,20(b) Refund/Political Party Committees,20(c) Refund/Other Political Committees,20(d) Total Contribution Refunds,21. Other Disbursements,22. Total Disbursements,23. Cash Beginning Reporting Period,24. Total Receipts this Period,25. SubTotal,26. Total Disbursements this Period,27. Cash on hand at Close Period,(6a) Total Contributions (No Loans),(6b) Total Contribution Refunds,(6c) Net Contributions,(7a) Total Operating Expenditures,(7b) Total Offsets to Operating Expenditures,(7c) NET Operating Expenditures.,11(a.i) Individuals Itemized,11(a.ii) Individuals Unitemized,11(a.iii) Individuals Total,11(b) Political Party Committees,11(c) All Other Political Committees (PACS),11(d) The Candidate,11(e) Total Contributions,12. Transfers From Other AUTH Committees,13(a) Loans made or guarn. by the Candidate,13(b) All Other Loans,13(c) Total Loans,14. Offsets to Operating Expenditures,15. Other Receipts,16. Total Receipts,17 Operating Expenditures,18. Transfers To Other AUTH Committees,19(a) Loan Repayment By Candidate,"19(b) Loan Repayments, ALL Other Loans",19(c) Total Loan Repayments,20(a) Refund/Individuals Other than Pol. Cmtes,"20(b) Refund, Political Party Committees","20(c) Refund, Other Political Committees",20(d) Total Contributions Refunds,21. Other Disbursements,22. Total Disbursements,NAME/TREASURER (as signed),DATE (Signed),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F3S,FORM TYPE,FILER FEC CMTE ID,(6a) Total Contributions (No Loans),(6b) Total Contribution Refunds,(6c) Net Contributions,(7a) Total Operating Expenditures,(7b) Total Offsets to Operating Expenditures,(7c) NET Operating Expenditures.,11(a.i) Individuals Itemized,11(a.ii) Individuals Unitemized,11(a.iii) Individuals Total,11(b) Political Party Committees,11(c) All Other Political Committees (PACS),11(d) The Candidate,11(e) Total Contributions,12. Transfers From Other AUTH Committees,13(a) Loans made or guarn. by the Candidate,13(b) All Other Loans,13(c) Total Loans,14. Offsets to Operating Expenditures,15. Other Receipts,16. Total Receipts,17 Operating Expenditures,18. Transfers To Other AUTH Committees,19(a) Loan Repayment By Candidate,"19(b) Loan Repayments, ALL Other Loans",19(c) Total Loan Repayments,20(a) Refund/Individuals Other than Pol. Cmtes,"20(b) Refund, Political Party Committees","20(c) Refund, Other Political Committees",20(d) Total Contributions Refunds,21. Other Disbursements,22. Total Disbursements,Date - General Election,Date - Day after General Election,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F3P,FORM TYPE,FILER FEC CMTE ID,COMMITTEENAME,STREET 1,STREET 2,CITY,STATE,ZIP,CHG OF ADDRESS,ACTIVITY PRIMARY,ACTIVITY GENERAL,RPTCODE,RPTPGI,DATE (Of Election),STATE (Of Election),DATE (Coverage From),DATE (Coverage To),6. Cash on Hand Beginning Period,7. Total Receipts,8. SubTotal,9. Total Disbursements,10. Cash on Hand Close of Period,11. Debts to,12. Debts by,13. Expenditures Subject to Limits,14. Net Contributions,15. Net Operating Expenditures,16. Federal Funds,17(a) Individuals,17(b) Political Party Committees,17(c) Other Political Committees (PACs),17(d) The Candidate,17(e) Total Contributions,18. Transfers From Aff/Other Party Committees,19(a) Received from or Guaranteed by Candidate,19(b) Other Loans,19(c) Total Loans,20(a) Operating,20(b) Fundraising,20(c) Legal and Accounting,20(d) Total offsets to Expenditures,21. Other Receipts,22. Total Receipts,23. Operating Expenditures,24. Transfers to Other Authorized Committees,25. Fundraising Disbursements,26. Exempt Legal and Accounting Disbursements,27(a) Made or guaranteed by Candidate,27(b) Other Repayments,27(c) Total Loan Repayments Made,28(a) Individuals,28(b) Political Party Committees,28(c) Other Political Committees,28(d) Total Contributions Refunds,29. Other Disbursements,30. Total Disbursements,31. Items on Hand to be Liquidated,ALABAMA,ALASKA,ARIZONA,ARKANSAS,CALIFORNIA,COLORADO,CONNECTICUT,DELAWARE,DIST OF COLUMBIA,FLORIDA,GEORGIA, HAWAII,IDAHO,ILLINOIS,INDIANA,IOWA,KANSAS,KENTUCKY,LOUISIANA,MAINE,MARYLAND,MASSACHUSETTS,MICHIGAN,MINNESOTA,MISSISSIPPI,MISSOURI, MONTANA,NEBRASKA,NEVADA,NEW HAMPSHIRE,NEW JERSEY,NEW MEXICO,NEW YORK,NORTH CAROLINA,NORTH DAKOTA,OHIO,OKLAHOMA,OREGON,PENNSYLVANIA,RHODE ISLAND,SOUTH CAROLINA,SOUTH DAKOTA,TENNESSEE,TEXAS,UTAH,VERMONT,VIRGINIA,WASHINGTON,WEST VIRGINIA,WISCONSIN,WYOMING,PUERTO RICO,GUAM,VIRGIN ISLANDS,TOTALS,16. Federal Funds,17(a) Individuals,17(b) Political Party Committees,17(c) Other Political Committees (PACs),17(d) The Candidate,17(e) Total contributions (Other than Loans),18. Transfers From Aff/Other Party Committees,19(a) Received from or Guaranteed by Candidate,19(b) Other Loans,19(c) Total Loans,20(a) Operating,20(b) Fundraising,20(c) Legal and Accounting,20(d) Total Offsets to Operating Expenditures,21. Other Receipts,22. Total Receipts,23. Operating Expenditures,24. Transfers to Other Authorized Committees,25. Fundraising Disbursements,26. Exempt Legal and Accounting Disbursements,27(a) Made or Guaranteed by the Candidate,27(b) Other Repayments,27(c) Total Loan Repayments Made,28(a) Individuals,28(b) Political Party Committees,28(c) Other Political Committees,28(d) Total Contributions Refunds,29. Other Disbursements,30. Total Disbursements,ALABAMA,ALASKA,ARIZONA,ARKANSAS,CALIFORNIA,COLORADO,CONNECTICUT,DELAWARE,DIST OF COLUMBIA,FLORIDA,GEORGIA,HAWAII,IDAHO,ILLINOIS,INDIANA,IOWA,KANSAS,KENTUCKY,LOUISIANA,MAINE,MARYLAND,MASSACHUSETTS,MICHIGAN,MINNESOTA,MISSISSIPPI,MISSOURI,MONTANA,NEBRASKA,NEVADA,NEW HAMPSHIRE,NEW JERSEY,NEW MEXICO,NEW YORK,NORTH CAROLINA,NORTH DAKOTA,OHIO,OKLAHOMA,OREGON,PENNSYLVANIA,RHODE ISLAND,SOUTH CAROLINA,SOUTH DAKOTA,TENNESSEE,TEXAS,UTAH,VERMONT,VIRGINIA,WASHINGTON,WEST VIRGINIA,WISCONSIN,WYOMING,PUERTO RICO,GUAM,VIRGIN ISLANDS,TOTALS,NAME/TREASURER (as signed),DATE (Signed) F3PS,FORM TYPE,FILER FEC CMTE ID,14. Net Contributions,15. Net Expenditures,16. Federal Funds,17(a) Individuals,17(b) Political Party Committees,17(c) Other Political Committees (PACs),17(d) The Candidate,17(e) Total contributions (Other than Loans),18. Transfers From Aff/Other Party Committees,19(a) Received from or Guaranteed by Candidate,19(b) Other Loans,19(c) Total Loans,20(a) Operating,20(b) Fundraising,20(c) Legal and Accounting,20(d) Total Offsets to Operating Expenditures,21. Other Receipts,22. Total Receipts,23. Operating Expenditures,24. Transfers to Other Authorized Committees,25. Fundraising Disbursements,26. Exempt Legal and Accounting Disbursements,27(a) Made or Guaranteed by the Candidate,27(b) Other Repayments,27(c) Total Loan Repayments Made,28(a) Individuals,28(b) Political Party Committees,28(c) Other Political Committees,28(d) Total Contributions Refunds,29. Other Disbursements,30. Total Disbursements,ALABAMA,ALASKA,ARIZONA,ARKANSAS,CALIFORNIA,COLORADO,CONNECTICUT,DELAWARE,DIST OF COLUMBIA,FLORIDA,GEORGIA,HAWAII,IDAHO,ILLINOIS,INDIANA,IOWA,KANSAS,KENTUCKY,LOUISIANA,MAINE,MARYLAND,MASSACHUSETTS,MICHIGAN,MINNESOTA,MISSISSIPPI,MISSOURI,MONTANA,NEBRASKA,NEVADA,NEW HAMPSHIRE,NEW JERSEY,NEW MEXICO,NEW YORK,NORTH CAROLINA,NORTH DAKOTA,OHIO,OKLAHOMA,OREGON,PENNSYLVANIA,RHODE ISLAND,SOUTH CAROLINA,SOUTH DAKOTA,TENNESSEE,TEXAS,UTAH,VERMONT,VIRGINIA,WASHINGTON,WEST VIRGINIA,WISCONSIN,WYOMING,PUERTO RICO,GUAM,VIRGIN ISLANDS,TOTALS,Date - General Election,Date - Day after General Election,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F3P31,FORM TYPE,FILER FEC CMTE ID,ENTITY TYPE,NAME (Contributor/Lender),STREET 1,STREET 2,CITY,STATE,ZIP,RPTPGI,INDEMP,INDOCC ,DATE (Of Contribution),FAIR MARKET VALUE OF ITEM,TRANSACTION CODE,TRANSDESC,FEC COMMITTEE ID NUMBER,FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE ,CAN/DIST,CONDUIT NAME,CONDUIT STREET 1,CONDUIT STREET 2,CONDUIT CITY,CONDUIT STATE,CONDUIT ZIP,MEMO CODE,MEMO TEXT,AMENDED CD,TRAN ID,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F3X,FORM TYPE,FILER FEC CMTE ID,COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,CHG OF ADDRESS,QUALIFIED CMTE ,RPTCODE,RPTPGI,DATE (Of Election),STATE (Of Election),DATE (Coverage From),DATE (Coverage To),6(b) Cash on Hand beginning,6(c) Total Receipts,6(d) Subtotal,7. Total Disbursements,8. Cash on Hand at Close,9. Debts to,10. Debts by,11(a)i Itemized,11(a)ii Unitemized,11(a)iii Total,11(b) Political Party Committees,11(c) Other Political Committees (PACs),11(d) Total Contributions,12. Transfers from Affiliated/Other Party Cmtes,13. All Loans Received,14. Loan Repayments Received,15. Offsets to Operating Expenditures (refunds ...),16. Refunds of Federal Contributions,17. Other Federal Receipts (dividends),18. Transfers from Nonfederal Account,19. Total Receipts,20. Total Federal Receipts,21(a)i Federal Share,21(a)ii Non-Federal Share,21(b) Other Federal Operating Expenditures,21(c) Total Operating Expenditures,22. Transfers to Affiliated/Other Party Cmtes,23. Contributions to Federal Candidates/Cmtes,24. Independent Expenditures,25. Coordinated Expenditures made by Party Cmtes,26. Loan Repayments,27. Loans Made,28(a) Individuals/Persons,28(b) Political Party Committees,28(c) Other Political Committees,28(d) Total Contributions Refunds,29. Other Disbursements,30. Total Disbursements,31. Total Federal Disbursements,32. Total Contributions,33. Total Contribution Refunds,34. Net Contributions,35. Total Federal Operating Expenditures,36. Offsets to Operating Expenditures,37. Net Operating Expenditures," 6(a) Cash on Hand Jan 1, 19",Year for Above,6(c) Total Receipts,6(d) Subtotal,7. Total disbursements,8. Cash on Hand Close,11(a)i Itemized,11(a)ii Unitemized,11(a)iii Total,11(b) Political Party committees,11(c) Other Political Committees (PACs),11(d) Total Contributions,12. Transfers from Affiliated/Other Party Cmtes,13. All Loans Received,14. Loan Repayments Received,15. Offsets to Operating Expenditures (refunds),16. Refunds of Federal Contributions,17. Other Federal Receipts (dividends),18. Transfers from Nonfederal Account,19. Total Receipts,20. Total Federal Receipts,21(a)i Federal Share,21(a)ii Non-Federal Share,21(b) Other Federal Operating Expenditures,21(c) Total operating Expenditures,22. Transfers to Affiliated/Other Party Cmtes,23. Contributions to Federal Candidates/Cmtes,24. Independent Expenditures,25. Coordinated Expenditures made by Party Cmtes,26. Loan Repayments Made,27. Loans Made,28(a) Individuals/Persons,28(b) Political Party Committees,28(c) Other Political Committees,28(d) Total contributions Refunds,29. Other Disbursements,30. Total Disbursements,31. Total Federal Disbursements,32. Total Contributions,33. Total Contribution Refunds,34. Net contributions,35. Total Federal Operating Expenditures,36. Offsets to Operating Expenditures,37. Net Operating Expenditures,NAME/TREASURER (as signed),DATE (Signed),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F3Z,FORM TYPE,FILER FEC CMTE ID (PCC),COMMITTEE NAME (PCC),DATE (Coverage From),DATE (Coverage To),FEC COMMITTEE ID NUMBER (Auth),COMMITTEE NAME (Auth),(a) 11(a)iii individuals total,(b) 11(b) Political party committees,(c) 11(c) other pol. committees (PACs),(d) 11(d) the candidate,(e) 11(e) total contributions,(f) 12. Transfers from other auth cmtes,(g) 13(a) made or guarn. by candidate,(h) 13(b) all other loans,(i) 13(c) total loans,(j) 14. offsets to operating expend,(k) 15. Other receipts,(l) 16. total receipts,(m) 17. Operating Expenditures,(n) 18. Transfers to other auth cmtes,(o) 19(a) made or guaranteed by cand,(p) 19(b) all other loans,(q) 19(c) total loan repayments,(r) 20(a) total refunds individuals,(s) 20(b) Refunds Political Pty cmtes,(t) 20(c) Refunds other Polit. cmtes,(u) 20(d) total contribution refunds,(v) 21. Other disbursements,(w) 22. Total disbursements,(x) 23. COH beginning reporting period,(y) 27. COH at close of period,(z) 9. Debts to,(aa) 12. Debts by,(bb) 6(c) net contributions,(cc) 7(c) net operating expenditures,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F4,FORM TYPE,FILER FEC CMTE ID,COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,COMMITTEE/ORG TYPE,DESC ,RPTCODE,DATE (Coverage From),DATE (Coverage To),6.(b) cash on hand beg. report per.,6.(c) Total receipts,6.(d) Subtotal,7. Total disbursements,8. COH CLOSE,9. Debts to,10. Debts by,11. Convention expenditures,12. refunds/rebates/returns relating to conv exp.,12(a) Expenditures subject to limits,12(b) expend. from prior years subject to limits,12(c) total expenditures subject to limits,13. Federal Funds SCH A,14(a) Itemized,14(b) unitemized,14(c) subtotal,15. Transfers from affiliated cmtes.,16(a) loans received,16(b) loan repayments received,16(c) subtotal loans/repayments,17(a) Itemized,17(b) unitemized,17(c) subtotal,18(a) Itemized,18(b) unitemized,18(c) subtotal,19(a) Itemized,19(b) unitemized,19(c) subtotal,20. total receipts,21(a) Itemized,21(b) unitemized,21(c) subtotal,22. Transfers to Affiliated Cmtes,23(a) loans made,23(b) loan repayments made,23(c) subtotal,24(a) Itemized,24(b) unitemized,24(c) subtotal,25. Total disbursements,6.(a) Cash on Hand,6.(a) 19 -- (YEAR),6.(c) Total receipts,6.(d) Subtotal,7. Total disbursements,8. COH CLOSE,11. Convention expenditures,12. refunds/rebates/returns relating to conv exp.,12(a) Expenditures subject to limits,12(b) expend. from prior years subject to limits,12(c) total expenditures subject to limits,13. Federal Funds,14(c) subtotal,15. Transfers from affiliated cmtes.,16(c) subtotal loans/repayments,17(c) subtotal,18(c) subtotal,19(c) subtotal,20. total receipts,21(c) subtotal,22. Transfers to Affiliated Cmtes,23(c) subtotal,24(c) subtotal,25. Total disbursements,NAME/TREASURER (as signed),DATE (Signed),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F5,FORM TYPE,FILER FEC CMTE ID,COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,CHG OF ADDRESS,YESNO (Qual/Non Q),INDEMP,INDOCC,RPTCODE,RPTPGI,DATE (Of Election),STATE (Of Election),DATE (Coverage From),DATE (Coverage To),TOTAL CONTRIBUTION,TOTAL INDEP. EXPEND,IND/NAME (Person Completing Form),DATE (Signed),DATE (Notarized),DATE (Notary Commission Expires),IND/NAME (Notary),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F56, FORM TYPE ,FILER FEC CMTE ID,ENTITY TYPE,NAME (Contributor/Lender),STREET 1,STREET 2,CITY,STATE,ZIP,INDEMP,INDOCC,DATE (Of Contribution),AMOUNT,FEC COMMITTEE ID NUMBER,FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE,CAN/DIST,CONDUIT NAME,CONDUIT STREET 1,CONDUIT STREET 2,CONDUIT CITY,CONDUIT STATE,CONDUIT ZIP,AMENDED CD,TRAN ID,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F57,FORM TYPE,FILER FEC CMTE ID,ENTITY TYPE,NAME (Payee),STREET 1,STREET 2,CITY,STATE,ZIP,TRANSDESC,DATE (Of Expenditure),AMOUNT,SUPPORT/OPPOSE ,S/O FEC CAN ID NUMBER,S/O CAN/NAME,S/O CAN/OFFICE,S/O CAN/STATE,S/O CAN/DIST,FEC COMMITTEE ID NUMBER,Unused field,Unused field,Unused field,Unused field,Unused field,CONDUIT NAME,CONDUIT STREET 1,CONDUIT STREET 2,CONDUIT CITY,CONDUIT STATE,CONDUIT ZIP,AMENDED CD,TRAN ID,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F6,FORM TYPE,FILER FEC CMTE ID,COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE ,CAN/DIST,DATE (Signed),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F65,FORM TYPE,FILER FEC CMTE ID,ENTITY TYPE,NAME (Contributor/Lender),STREET 1,STREET 2,CITY,STATE,ZIP,INDEMP,INDOCC,DATE (Of Contribution),AMOUNT,FEC COMMITTEE ID NUMBER,FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE ,CAN/DIST,CONDUIT NAME,CONDUIT STREET 1,CONDUIT STREET 2,CONDUIT CITY,CONDUIT STATE,CONDUIT ZIP,AMENDED CD,TRAN ID,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F7,FORM TYPE,FILER FEC CMTE ID,COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,ORGANIZATION TYPE,RPTCODE,DATE (Of Election),STATE (Of Election),DATE (Coverage From),DATE (Coverage To),TOTAL COSTS,NAME/FILER (as signed),DATE (Signed),TITLE,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F76,FORM TYPE,FILER FEC CMTE ID,COMMUNICATION TYPE,TRANSDESC (Comm. Descrip),COMMUNICATION CLASS,DATE (Of Communication),SUPPORT/OPPOSE ,FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE ,CAN/DIST,RPTPGI,COST OF COMMUNICATION,AMENDED CD,TRAN ID,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F8,FORM TYPE,FILER FEC CMTE ID,COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,1. CASH ON HAND,1(a). as of,2. Total assets to be liquidated,3. Total (assets),4. Year to date receipts,5. Year to date disbursements,6. Total amount of debts owed by cmte,7. Total number of creditors owed,8. Number of creditors in part II of this plan,9. Total amount of debts owed to creditors in part II of plan,10. Total amount to be paid to creditors,11. YESNO (Is the cmte terminating activities),11. Y DATE (PLANNED FOR TERMINATION RPT),12. YESNO (If this is an auth cmtte are there other auth cmtte.) ,12. Y DESC (Y IF YES list AUTH CMTE ID/NAMES),13. YESNO (sufficient funds to pay total amount indicated in this plan),13. N DESC (N If NO what steps will be taken to obtain the funds),14. YESNO (Has the committee filed previous debt settlement plans),15. YESNO (After disposing ... will there be any residual funds?),15. Y DESC (IF YES how will the funds be disbursed),PART III YESNO (Does cmtte have sufficient funds to pay the remaining,"PART III DESC (N If no, what steps will be taken to obtain the funds.)",NAME/TREASURER (as signed),DATE (Signed),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F82,FORM TYPE,FILER FEC CMTE ID,CREDITOR CODE,NAME (Contributor/Lender),STREET 1,STREET 2,CITY,STATE,ZIP,DATE (Incurred),AMOUNT OWED TO,AMOUNT OFFERED IN,A. DESC (Initial Terms And Nature Of Debt),B. DESC (Efforts Made By Cmte To Pay Debt),C. DESC (Steps Taken By Creditor To Collect),D. YESNO (effort made by creditor to collect...,D. DESC (N If No Explain),E. YESNO (terms of debt settlement comparable...,E. DESC (N If No Explain),FEC COMMITTEE ID NUMBER,FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE ,CAN/DIST,NAME of creditor or representative,DATE (Signed),AMENDED CD,TRAN ID,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F83,FORM TYPE,FILER FEC CMTE ID,CREDITOR CODE,NAME (Contributor/Lender),STREET 1,STREET 2,CITY,STATE,ZIP,YESNO (Is This A Disputed Debt),DATE (Incurred),AMOUNT OWED TO CREDITOR,AMOUNT EXPECTED TO,FEC COMMITTEE ID NUMBER,FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE,CAN/DIST,AMENDED CD,TRAN ID,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, F99,FORM TYPE,FILER FEC CMTE ID,COMMITTEE NAME ,STREET 1,STREET 2,CITY,STATE,ZIP,NAME/TREASURER (as signed),DATE (Signed),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, SchA,FORM TYPE,FILER FEC CMTE ID,ENTITY TYPE, CONTRIBUTOR NAME,STREET 1,STREET 2,CITY,STATE,ZIP,ITEM ELECT CD,ITEM ELECT OTHER,INDEMP,INDOCC,AGGREGATE AMT Y-T-D,DATE RECEIVED,AMOUNT RECEIVED,TRANS CODE,TRANS DESCRIP,FEC COMMITTEE ID NUMBER,FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE ,CAN/DIST,CONDUIT NAME,CONDUIT STREET1,CONDUIT STREET2,CONDUIT CITY,CONDUIT STATE,CONDUIT ZIP,MEMO CODE,MEMO TEXT,AMENDED CD,TRAN ID,BACK REF TRAN ID,BACK REF SCHED NAME,NAT CMTTE NON-FED ACCT,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, SchB,FORM TYPE,FILER FEC CMTE ID,ENTITY TYPE,RECIPIENT NAME,STREET 1,STREET 2,CITY,STATE,ZIP,TRANS CODE,TRANS DESCRIP,ITEM ELECT CD,ITEM ELECT OTHER,DATE OF EXPENDITURE,AMOUNT OF EXPENDITURE,FEC COMMITTEE ID NUMBER,FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE ,CAN/DIST,CONDUIT NAME,CONDUIT STREET 1,CONDUIT STREET 2,CONDUIT CITY,CONDUIT STATE,CONDUIT ZIP,MEMO CODE,MEMO TEXT, AMENDED CD,TRAN ID,BACK REF TRAN ID,BACK REF SCHED NAME,NAT CMTTE NON-FED ACCT,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, SchC,FORM TYPE,FILER FEC CMTE ID, ENTITY TYPE,NAME (Loan Source),STREET 1,STREET 2,CITY,STATE,ZIP,ELECTION ,ELECTION DESCRIPTION,ORIG. AMT OF LOAN,PAYMENT TO DATE,LOAN BALANCE,DATE (Incurred),DUE DATE TERMS,PCT RATE TERMS,SECURED YESNO,FEC COMMITTEE ID NUMBER,FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE ,CAN/DIST,AMENDED CD,TRAN ID,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, SchC1,FORM TYPE,FILER FEC CMTE ID,BACK REFERENCE TRAN ID,ENTITY TYPE,NAME (Loan Source),STREET 1,STREET 2,CITY,STATE, ZIP,AMT OF LOAN,LOAN INTEREST RATE PERCENT,DATE (Incurred),DATE (Due),A1.YESNO (Loan Restructured),A2. DATE (Of Original Loan),B.1. CREDIT AMOUNT THIS DRAW,B.2. TOTAL BALANCE,C. YESNO (Others liable?),D. YESNO (Collateral?),D.1 DESC (Collateral),D.2 COLLATERAL VALUE/AMOUNT,D.3 YESNO (Perfected Interest?)),E.1 YESNO (Future Income),E.2 DESC (Specification of the above),E.3 ESTIMATED VALUE,E.4 DATE (Depository account established),E.5 IND/NAME (Account Location),E.6 STREET 1,E.7 STREET 2,E.8 CITY,E.9 STATE,E.10 ZIP,E.11 DEP ACCT AUTH DATE (Presidential),F. DESC (State basis of loan),G. NAME/TREASURER (as signed),G. SIG/DATE,H. NAME/AUTH (as signed),H. AUTH/TITLE ,H. AUTH/SIG DATE,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, SchC2,FORM TYPE,FILER FEC CMTE ID,BACK REFERENCE TRAN ID,IND/NAME (Endorser/Guarantor),STREET 1,STREET 2,CITY,STATE,ZIP,INDEMP,INDOCC,AMOUNT GUARANTEED BALANCE,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, SchD,FORM TYPE,FILER FEC CMTE ID,ENTITY TYPE,NAME (Debtor/Creditor),STREET 1,STREET 2,CITY,STATE,ZIP,NATURE/PURPOSE DEBT DESCRIPTION,BEGINNING BALANCE,INCURRED THIS PERIOD,PAYMENT THIS PERIOD,BALANCE AT CLOSE,FEC COMMITTEE ID NUMBER,FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE,CAN/DIST,CONDUIT NAME,CONDUIT STREET 1,CONDUIT STREET 2,CONDUIT CITY,CONDUIT STATE,CONDUIT ZIP,AMENDED CD,TRAN ID,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, SchE,FORM TYPE,FILER FEC CMTE ID,ENTITY TYPE,NAME (Payee),STREET 1,STREET 2,CITY,STATE,ZIP,TRANSDESC ,DATE,AMOUNT EXPENDED,SUPPORT/OPPOSE ,S/O FEC CAN ID NUMBER,S/O CAN/NAME,S/O CAN/OFFICE,S/O STATE,S/O CAN/DIST,FEC COMMITTEE ID NUMBER,Unused field,Unused field,Unused field,Unused field,Unused field,CONDUIT NAME,CONDUIT STREET 1,CONDUIT STREET 2,CONDUIT CITY,CONDUIT STATE,CONDUIT ZIP,IND/NAME (as signed),DATE (Signed),DATE (Notarized),DATE (Notary Commission Expires),IND/NAME (Notary),AMENDED CD,TRAN ID,MEMO CODE,MEMO TEXT,BACK REF TRAN ID,BACK REF SCHED NAME,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, SchF,FORM TYPE,FILER FEC CMTE ID,DESIG YES/NO (Has Filer Been Desig.To Make Cord.Expend.),FEC COMMITTEE ID NUMBER (Designating),COMMITTEE NAME,FEC COMMITTEE ID NUMBER (Subordinating),COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,ENTITY TYPE,NAME (Payee),STREET 1,STREET 2,CITY,STATE,ZIP,AGG. GEN. ELE. AMOUNT EXPENDED,TRANSDESC ,DATE,AMOUNT,FEC COMMITTEE ID NUMBER,FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE ,CAN/DIST,CONDUIT NAME,CONDUIT STREET 1,CONDUIT STREET 2,CONDUIT CITY,CONDUIT STATE,CONDUIT ZIP,AMENDED CD,TRAN ID,MEMO CODE,MEMO TEXT,BACK REF TRAN ID,BACK REF SCHED NAME,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, SchH1,FORM TYPE,FILER FEC CMTE ID,NAT PARTY CMTES %,HSE/SEN PTY CMTES MINIMUM FED %,HSE/SEN PTY CMTES PERCENTAGE ESTIMATED FEDERAL CAN SUPPORT,HSE/SEN PTY CMTES PERCENTAGE ESTIMATED NON FEDERAL CAN SUPPORT,HSE/SEN PTY CMTES ACTUAL FEDERAL CAN SUPPORT,HSE/SEN PTY CMTES ACTUAL NON FEDERAL CAN SUPPORT,HSE/SEN PTY CMTES PERCENTAGE ACTUAL FEDERAL,SEP. SEG FUNDS & PERCENTAGE NON CONNECTED CMTES ESTIMATED FEDERAL CANDIDATE SUPPORT ,SEP. SEG FUNDS & PERCENTAGE NON CONNECTED CMTES ESTIMATED NON FEDERAL CANDIDATE SUPPORT ,SEP. SEG FUNDS & NON CONNECTED CMTES ACTUAL FEDERAL CANDIDATE SUPPORT ,SEP. SEG FUNDS & NON CONNECTED CMTES ACTUAL NON FEDERAL CANDIDATE SUPPORT ,SEP. SEG FUNDS & PERCENTAGE NON CONNECTED CMTES ACTUAL FEDERAL CANDIDATE SUPPORT ,1. BALLOT COMP PRES BLANK OR 1,2. BALLOT COMP SEN BLANK OR 1,3. BALLOT COMP HSE BLANK OR 1,4. SUBTOTAL FED,5. BALLOT COMP GOV BLANK OR 1,6. OTHER STATEWIDE,7. STATE SENATE,8. STATE REP.,"9. LOCAL CANDIDATES BLANK, 1 OR 2",10. EXTRA NON-FED POINT BLANK OR 1,11. SUBTOTAL,12. TOTAL POINTS,FEDERAL ALLOCATION PERCENTAGE,AMENDED CD,TRAN ID,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, SchH2,FORM TYPE,FILER FEC CMTE ID,IND/NAME (Activity/Event),YESNO (Activity Is Fundraising),YESNO (Activity Is Exempt),YESNO (Act. Direct Can Support),RATIO CODE,FEDERAL PERCENTAGE,NON-FEDERAL PERCENTAGE,AMENDED CD,TRAN ID,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, SchH4,FORM TYPE,FILER FEC CMTE ID,BACK-REF TRAN ID,ACCOUNT NAME,EVENT NAME,EVENT TYPE,DATE (Of Receipt),AMOUNT TRANSFERRED,TOTAL AMOUNT TRANSFERRED,AMENDED CD,TRAN ID,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, SchH4,FORM TYPE,FILER FEC CMTE ID,ENTITY TYPE,NAME (Payee),STREET 1,STREET 2,CITY,STATE,ZIP,PURPOSE/EVENT ,DATE,TOTAL AMOUNT,FEDERAL SHARE,NON FEDERAL SHARE,YESNO (Activity Is Admin./Voter Drive),YESNO (Activity Is Fundrainsig),YESNO (Activity Is Exempt),YESNO (Act. Direct Can Support),EVENT YEAR-TO-DATE,ADDITIONAL DESCRIPTION,FEC COMMITTEE ID NUMBER,FEC CANDIDATE ID NUMBER,CANDIDATE NAME,CAN/OFFICE,CAN/STATE,CAN/DIST,CONDUIT NAME,CONDUIT STREET 1,CONDUIT STREET 2,CONDUIT CITY,CONDUIT STATE,CONDUIT ZIP,AMENDED CD,TRAN ID,MEMO CODE,MEMO TEXT,BACK REF TRAN ID,BACK REF SCHED NAME,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, SchI,FORM TYPE,FILER FEC CMTE ID,Bank Account ID Number,NAME (Of Account),DATE (Coverage From),DATE (Coverage To),1. Total Receipts,2. Transfers to FED or allocation,3. Transfers to state/local Party organizations,4. Direct state/local candidate support,5. Other Disbursements,6. Total Disbursements,7. Beginning COH,8. Receipts,9. Subtotal,10. Disbursements,11. Ending COH,1. Total receipts,2. Transfers to FED or allocation,3. Transfers to state/local Party organizations,4. Direct state/local candidate support,5. Other Disbursements,6. Total Disbursements,7. Beginning COH (as of Jan 1),8. Receipts,9. Subtotal,10. Disbursements,11. Ending COH,AMENDED CD,TRAN ID,Account Number for Account named in Field #4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, TEXT,REC TYPE,FORM TYPE,BACK REF TRAN ID,TEXT4000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -------------------------------------------------------------------------------- /spec/sources/headers/ignore.csv: -------------------------------------------------------------------------------- 1 | COLUMN A REPORT TOTALS 2 | COLUMN B YEAR-TO-DATE TOTALS 3 | COLUMN B YTD TOTALS - LEVIN ACTIVITY 4 | (New line 30 fields added to end of this layout) 5 | (New line 18(b) & 18(c) fields at end of layout) -------------------------------------------------------------------------------- /spec/sources/sa.csv: -------------------------------------------------------------------------------- 1 | canonical,^7,,^6,,^[2-5],, form_type,1,FORM TYPE,1,FORM TYPE,1,FORM TYPE, ,--,Column B Amounts:,--,Column B Amounts:,,COLUMN B CYCLE-TO-DATE TOTALS, date_coverage_from,2,FORM TYPE,,FORM TYPE,,, date_coverage_to,,,,,,, aggregate,3,FORM TYPE,3,FORM TYPE,3,FORM TYPE,3 ,4,Column B Amounts:,--,Column B Amounts:,,COLUMN B CYCLE-TO-DATE TOTALS, -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'fech' 3 | 4 | RSpec.configure do |config| 5 | config.mock_framework = :mocha 6 | end 7 | -------------------------------------------------------------------------------- /spec/translator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Fech::Translator do 4 | 5 | describe "#add_translation" do 6 | 7 | before do 8 | @translator = Fech::Translator.new 9 | end 10 | 11 | it "should ignore case when specified options are regular expressions" do 12 | @translator.convert(:row => /^foo/, :field => 'bar') {} 13 | @translator.get_translations(:row => "FoO", :field => 'bar', :action => :convert).size.should == 1 14 | end 15 | 16 | end 17 | 18 | describe ".convert" do 19 | 20 | before do 21 | @translator = Fech::Translator.new 22 | end 23 | 24 | it "should add a new translation to instance's list" do 25 | lambda { 26 | @translator.convert(:row => 'foo', :field => 'bar') {} 27 | }.should change{@translator.translations.count}.by(1) 28 | end 29 | 30 | it "should save a given block as part of the translation" do 31 | lambda { 32 | @translator.convert(:row => 'foo', :field => 'bar') {|v| Date.parse(v)} 33 | }.should_not raise_error 34 | @translator.translations.first[:proc].should_not be_nil 35 | end 36 | 37 | it "should raise error if no block is given" do 38 | lambda { 39 | @translator.convert(:row => 'foo', :field => 'bar') 40 | }.should raise_error 41 | end 42 | 43 | it "should not fail if not passed any limiting parameters" do 44 | lambda { 45 | @translator.convert {} 46 | }.should_not raise_error 47 | end 48 | 49 | it "should set defaults for unspecified parameters" do 50 | @translator.convert {} 51 | t = @translator.translations.last 52 | t[:row].should == /.*/i 53 | t[:field].should == /.*/i 54 | t[:version].should == /.*/i 55 | end 56 | 57 | it "should return the translation hash" do 58 | ret = @translator.convert {} 59 | ret.class.should == Hash 60 | ret.keys.should =~ [:row, :field, :version, :proc, :action] 61 | end 62 | 63 | end 64 | 65 | describe ".combine" do 66 | 67 | before do 68 | @filing = Fech::Filing.new(723604) 69 | @filing.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', '723604.fec')) 70 | end 71 | 72 | it "should correctly compute derived fields" do 73 | @filing.translator.combine(:row => /F3PN/, :field => :combined) do |row| 74 | Date.parse(row[:coverage_through_date]) - Date.parse(row[:coverage_from_date]) 75 | end 76 | original = Date.parse(@filing.summary.coverage_through_date) - Date.parse(@filing.summary.coverage_from_date) 77 | @filing.summary.combined.should == original 78 | end 79 | 80 | it "should allow indexing by original field name" do 81 | @filing.translator.combine(:row => /F3PN/, :field => :combined) do |row| 82 | Date.parse(row[:coverage_through_date]) - Date.parse(row[:coverage_from_date]) 83 | end 84 | lambda { 85 | @filing.summary.coverage_through_date 86 | }.should_not raise_error 87 | end 88 | 89 | it "should allow indexing by aliased field names" do 90 | @filing.translate do |t| 91 | t.alias :alias_a, :coverage_from_date, /F3PN/ 92 | t.alias :alias_b, :coverage_through_date, /F3PN/ 93 | t.combine(:row => /F3PN/, :field => :combined) do |row| 94 | Date.parse(row[:alias_b]) - Date.parse(row[:alias_a]) 95 | end 96 | end 97 | lambda { 98 | @filing.summary 99 | }.should_not raise_error 100 | end 101 | 102 | end 103 | 104 | describe ".alias" do 105 | 106 | before do 107 | @translator = Fech::Translator.new 108 | end 109 | 110 | it "should add the given alias to @aliases" do 111 | @translator.alias(:new_name, :old_name, /hdr/) 112 | @translator.aliases.should =~ [{:row => /hdr/i, :alias => :new_name, :for => :old_name}] 113 | end 114 | 115 | it "should not require :row" do 116 | lambda { 117 | @translator.alias(:new_name, :old_name) 118 | }.should_not raise_error 119 | @translator.aliases.should =~ [{:row => /.*/i, :alias => :new_name, :for => :old_name}] 120 | end 121 | 122 | end 123 | 124 | describe ".applicable_translation?" do 125 | 126 | before do 127 | @row_type = "SA18" 128 | @field = "date_coverage_from" 129 | @translation = Fech::Translator.new.convert(:row => "SA", :field => @field, :version => "7.0") {|v| Date.parse(v)} 130 | end 131 | 132 | it "should return true if row and field are matches for the translation's regexes" do 133 | Fech::Translator.applicable_translation?(@translation, :row => @row_type, :field => @field).should == true 134 | end 135 | 136 | it "should return false if row, field, or version does not match" do 137 | Fech::Translator.applicable_translation?(@translation, :row => @row_type, :field => @field, :version => "6.0").should == false 138 | end 139 | 140 | it "should accept non-string values" do 141 | lambda { 142 | Fech::Translator.applicable_translation?(@translation, :row => Regexp.new(@row_type), :field => @field.to_s) 143 | }.should_not raise_error 144 | end 145 | 146 | it "should accept match parameters as a single opts hash" do 147 | lambda { 148 | Fech::Translator.applicable_translation?(@translation, {:row => Regexp.new(@row_type), :field => @field.to_s}) 149 | }.should_not raise_error 150 | Fech::Translator.applicable_translation?(@translation, {:row => Regexp.new(@row_type), :field => @field.to_s}).should == true 151 | end 152 | 153 | end 154 | 155 | describe ".get_translations" do 156 | 157 | before do 158 | @translator = Fech::Translator.new 159 | @translator.convert(:row => "sa", :field => :date_coverage_from) {|v| Date.parse(v)} 160 | @translator.convert(:row => "sa", :field => :date_coverage_to) {|v| Date.parse(v)} 161 | @translator.convert(:row => "sb", :field => /date.*/) {|v| Date.parse(v)} 162 | end 163 | 164 | it "should return only translations that match the parameters" do 165 | @translator.get_translations(:row => "sa").size.should == 2 166 | @translator.get_translations(:row => "sb").size.should == 1 167 | end 168 | 169 | it "should memoize output" do 170 | Fech::Translator.expects(:applicable_translation?).times(3).returns(true) 171 | @translator.get_translations(:row => "sa") 172 | @translator.get_translations(:row => "sa") 173 | end 174 | 175 | it "should only memoize based on unique key" do 176 | Fech::Translator.expects(:applicable_translation?).times(6).returns(true) 177 | @translator.get_translations(:row => "sa") 178 | @translator.get_translations(:row => "sb") 179 | end 180 | 181 | end 182 | 183 | describe "#add_default_translations" do 184 | 185 | before do 186 | @translator = Fech::Translator.new(:include => [:names]) 187 | end 188 | 189 | it "should add all specified translations by default" do 190 | @translator.translations.size.should > 0 191 | end 192 | 193 | end 194 | 195 | end -------------------------------------------------------------------------------- /tasks/fech.rake: -------------------------------------------------------------------------------- 1 | require 'fech' 2 | require 'rspec/core/rake_task' 3 | 4 | namespace :fech do 5 | 6 | desc "Recreate the column header maps from source .csv files" 7 | task :maps do 8 | # This will spit out a rendered mappings file, but will not be loaded by 9 | # the gem by default. To use the new file, move it into the lib/fech 10 | # folder of your active Fech gem. 11 | source = 'sources/' 12 | destination = ENV['destination'] || Dir.pwd 13 | 14 | if File.directory?(destination) 15 | destination = File.join(destination, 'rendered_maps.rb') 16 | end 17 | 18 | Fech::MapGenerator.convert_header_file_to_row_files(source) 19 | Fech::MapGenerator.dump_row_maps_to_ruby(source, destination) 20 | 21 | puts "Successfully wrote out mappings to #{destination}" 22 | end 23 | 24 | namespace :test do 25 | 26 | desc "Run all specs." 27 | RSpec::Core::RakeTask.new(:spec) do |t| 28 | t.pattern = 'spec/*_spec.rb' 29 | t.verbose = false 30 | end 31 | 32 | RSpec::Core::RakeTask.new(:coverage) do |t| 33 | t.rcov = true 34 | t.rcov_opts = %w{--exclude gems\/,spec\/,features\/,seeds\/ --sort coverage} 35 | t.verbose = true 36 | end 37 | 38 | end 39 | 40 | end 41 | --------------------------------------------------------------------------------