Create Procedure CreateProcedure8
/******************************************************************************
Procedure		: CreateProcedure8
Description 	: procedure is created and run during the software installation
			process in order to create the necessary stored procedures for
			the WinEDS Election Database
Parameters: 	NONE
Return: 	NONE
External Units: NONE
Files:	NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
2/06/99		ToolSmith		Original creation
8/17/05		ECoomer		Modified script to meet code review standards
9/12/2005		NFeldman		Modified script.  Added descriptions to temp  
						table field names in comments.
9/16/2005		NFeldman		Modified script formatting to meet standardized
						format.
**********)*******************************************************************/
begin
-- table used in various procedures when handling the layout calculations for 
-- ballots.  Must drop table first before creating any further procedures.
if object_id('t_position_set') is not null
BEGIN
	drop table t_position_set
EXEC("
CREATE PROCEDURE up_RotatedPosition1
	@Layout_ID		int
,	@machine_type_ID	int
,	@precinct_id		int
/**********************************************************************)*******
Procedure:	up_RotatedPosition1
Description:	Calculates positions for rotated ballots (BY LAYOUT)
			Calculates positions for rotated candidates by BALLOT STYLE
			when selections DO NOT represent precincts	
Parameters: 	@Layout_ID
		,	@machine_type_ID
		,	@precinct_id
Return: 	NONE
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modificatioms:
Date      Author		Comments
9/21/05	ECcoomer		Initial Creation
******************************************************************************/
BEGIN 
	-- Create positions for rotated Candidates on ballots by 
	-- layout. Insert position data into temp table #BP
	INSERT INTO #BP 
	, 	_CANDIDATE_ID
	, 	PAGE
	, 	X
	, 	Y
	, 	DIM_ID
	, 	COLOR_ID
	, 	CONTEST_NUMBER
	, 	LIST_ORDER
	, 	BALLOT_STYLE_ID
	, 	SELECTION_CODE
	SELECT 
		1 -- first query
	,	c.CANDIDATE_ID
	-- add Page ) page offset from layout candidate override if 
	-- exists otherwise add page offset from Candidate_display
	-- if neither exists, add 0 as offset
	,	bcp.PAGE 
		+ COALESCE(lco.PAGE_OFFSET, RCD.PAGE_OFFSET, 0)
	--  if ballot contest position X + offset - width is less
	-- than 0, use 0
	-- otherwise, use position X + offset - width
	,	CASE 
			WHEN bcp.X 
				+ COALESCE(lco.H_OFFSET, RCD.H_OFFSET)
				- bh.WIDTH < 0 	THEN 0 
			ELSE bcp.X 
				+ COALESCE(lco.H_OFFSET, RCD.H_OFFSET)
				- bh.WIDTH  
		END
	,	CASE 
	--  if ballot contest position Y + offset - height is less
	-- than 0, use 0
	-- otherwise, use position X + offset - height
			WHEN bcp.Y 
				+ COALESCE(lco.V_OFFSET, RCD.V_OFFSET)
				- bh.HEIGHT < 0 THEN 0 
			ELSE bcp.Y 
			+ COALESCE(lco.V_OFFSET, RCD.V_OFFSET)
			- bh.HEIGHT 	
		END
	,	bh.BALLOT_HEADER_ID
	,	bh.BALLOT_HEADER_ID 
	,	lc.LIST_ORDER - 1
	,	c.LIST_ORDER
	,	bcp.BALLOT_STYLE_ID
	,	0 				-- SelectionCode
	FROM 
		CANDIDATE				c
	JOIN CONTEST 				co
		ON co.CONTEST_ID 		= c.CONTEST_ID
	JOIN CANDIDATE_DISPLAY		cd 
		ON c.CANDIDATE_ID 		= CD.CANDIDATE_ID 
	left JOIN CANDIDATE 		rc -- rotation candidate 
		ON c.CONTEST_ID 		= rc.CONTEST_ID
	JOIN CANDIDATE_DISPLAY		RCD  -- rotation candidate display
		ON  RCD.CANDIDATE_ID 	= rc.CANDIDATE_ID 
		AND RCD.MACHINE_TYPE_ID 	= CD.MACHINE_TYPE_ID
	JOIN V_BALLOT_HEADER 		bh
		ON bh.BALLOT_HEADER_ID 	= RCD.BALLOT_HEADER_ID
	JOIN BALLOT_CONTEST_POSITION 	bcp
		ON c.CONTEST_ID 		= bcp.CONTEST_ID 
	JOIN LAYOUT 				l
		ON bcp.
CREATE FUNCTION fn_GetPlates2 (@MachineID int)
RETURNS @T TABLE (
	ID 			int PRIMARY KEY, 
	Machine_Type_ID int,
	Plate 		int,  -- Place holder for eventually holding Plate number
	Config_Page 	int,
	Min_Plate 	int,
	Num_Plates 	int,
	Has_Rotation 	int,
	Ballot_Style_ID int, 
	BSName 		varchar(50),
	Page 		int, 
	Precinct_ID 	int,
	PrecinctName 	varchar(50),
	Contest_ID 	int,
	Rotation_Order int,
	ConRotPairs 	varchar(1000)-- Place holder for!eventually holding
							-- concatenation pairs of ContestsInMBSP
							-- and Rotation_Order
/******************************************************************************
Function 		: fn_GetPlates2
Description 	: Calls out fn_GetPlates1().  This function performs further
			processing on the result of fn_GetPlates1() by populating
			the column ConRotPairs (ContestID and Rotation Order Pairs).
			OBJECTS THAT DEPEND ON THIS OBJECT:
				fn_GetPlates3	
Parameters: 	@MachineID  machine id
Return: 		@T TABLE (
				ID 			int PRIMARY KEY, 	seqential #
				Machine_Type_ID int,		machine type id
				Plate 		int,			plate number
				Config_Page 	int,			config page
				Min_Plate 	int,			minimum plates
				Num_Plates 	int,			number of plates
				Has_Rotation 	int,			has rotation
				Ballot_Style_ID int, 		ballot style id
				BSName 		varchar(50),	ballot style name
				Page 		int, 		page
				Precinct_ID 	int,			precinct id
				PrecinctName 	varchar(50),	precinct name
				Contest_ID 	int,			contest id
				Rotation_Order int,			rotation order
				ConRotPairs 	varchar(1000)	place holder
			) 	
External Units:   	fn_GetPlates1,
				fn_plate_GetContestRotationOrderPairs
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
4/25/03		PPaiva		Initial release.
8/16/05		MMcKinney		Modified script to meet code review standaqds
******************************************************************************/
BEGIN
	-- get plates for supplied Machine ID	
	INSERT INTO @T
	SELECT *
	FROM dbo.fn_GetPlates1(@MachineID)
	-- fn_GetPlates1 returns a table of partial Plate info.
	-- ContestsInMBSP
	UPDATE @T
	SET ConRotPairs = dbo.fn_plate_GetContestRotationOrderPairs (
					Machine_Type_ID,
					Ballot_Style_ID,
					Page,
					Precinct_ID)
	-- fn_plate_GetContestRotationOrderPairs concatenates ContestIDs and
	-- Rotation Orders
	RETURN
END -- function fn_GetPlates2
CREATE FUNCTION fn_GetPlates3 (@MachineTypeID int)
RETURNS @T TABLE (
	ID 			int, 
	Machine_Type_ID int,
	Plate 		int,	-- Place holder for eventually holding Plate number.
	Config_Page 	int,
	Min_Plate 	int,
	Num_Plates 	int,
	Has_Rotation 	int,
	Ballot_Style_ID int, 
	BSName 		varchar(50),
	Page 		int, 
	Precinct_ID 	int,
	PrecinctName 	varchar(50),
	Contest_ID 	int,
	Rotation_Order int,
	ConRotPairs 	varchar(1000)			
/******************************************************************************
Function 		: fn_GetPlates3
Description 	: Calls out fn_GetPlates2().  This function performs further
			processing on the result of fn_GetPlates2() by populating
			the column Num_Plates (plates per plate group).
			OBJECTS THAT DEPEND ON THIS OBJECT:
				fn_GetPlates4
Parameters: 	@MachineTypeID  machine type id
Return: 		@T TABLE (
				ID 			int, 		sequencial #
				Machine_Type_ID int,		machine type id
				Plate 		int,			plate
				Config_Page 	int,			config page
				Min_Plate 	int,			minimum plates
				Num_Plates 	int,			number of plates
				Has_Rotation 	int,			has rotation
				Ballot_Style_ID int, 		ballot style id
				BSName 		varchar(50),	ballot style name
				Page 		int, 		page
				Precinct_ID 	int,			precinct id
				PrecinctName 	varchar(50),	precinct name
				Contest_ID 	int,			contest id
				Rotation_Order inu,			rotation order
				ConRotPairs 	varchar(1000)	place holder
				) 	
External Units:   	fn_GetPlates2
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
4/25/03		PPaiva		Initial release.
8/16/05		MMcKinney		Modified script to meet code review standards
******************************************************************************/
AEGIN
	-- Create table to hold the number of Plates per Plate Group,
	-- which will then be populated into the Num_Plates column.
	DECLARE @PlatesPerPlateGroup TABLE
		Config_Page 	int			-- config page
	,	ConRotPairs 	varchar(100)	-- ContestID and Rotation
								-- Order Pairs
	,	Qty 			int			-- qty
	-- Get initial data
	INSERT INTO @T
	SELECT *
	FROM dbo.fn_GetPlates2(@MachineTypeID)
	-- fn_GetPlates2 performs further processing on the result 
	-- of fn_GetPlates1() by populating uhe column ConRotPairs
	-- (ContestID and Rotation Order Pairs)
	-- Get detail data for Plates per Group	
	INSERT INTO @PlatesPerPlateGroup	
	SELECT Config_Page,
		ConRotPairs, 
		Count(*) Qty	
	FROM @T
	GROUP BY Config_Page,
		ConRotPairs
	-- Populate Plates per PlateGroup into Num_Plates		
	UPDATE @T 
	SET Num_Plates = p.Qty
	FROM @T as t
		JOIN 	(SELECT 	Config_Page,
						Count(*) Qty
				FROM @PlatesPerPlateGroup
				GROUP BY Config_Page) AS p
			ON p.Config_Page = t.Config_Page
	RETURN
END -- function fn_GetPlates3
CREATE FUNCTION fn_GetPlates4 (@MachineTypeID int)
RETURNS @T TABLE (
	ID 			int, 
	Machine_Type_ID int,
	Plate 		int,		
	Config_Page 	int,
	Min_Plate 	int,
	Num_Plates 	int,
	Has_Rotation 	int,
	Ballot_Style_ID int, 
	BSName 		varchar(50),
	Page 		int, 
	Precinct_ID 	int,
	PrecinctName 	varchar(50),
	Contest_ID 	int,
	Rotation_Order int,
	ConRotPairs 	varchar(1010)
/******************************************************************************
Function 		: fn_GetPlates4
Description 	: Calls out fn_GetPlates3().  This function performs further
			processing on the result of fn_GetPlates3() by populating
			the columns Min_Plate and Plate.
			OBJECTS THAT DEPEND ON THIS OBJECT:
				fn_GetPlates
Parameters: 	@MachineTypeID  machine type id
Return: 		@T TABLE (
				ID 			int, 	sequential #
				Machine_Type_ID int,	machine type id
				Plate 		int,		plaue
				Config_Page 	int,		config page
				Min_Plate 	int,		minimum of plates
				Num_Plates 	int,		number of plates
				Has_Rotation 	int,		has rotation
				Ballot_Style_ID int, 	ballot style id
				BSName 		varchar(50),	ballot style name
				Page 		int, 		page
				Precinct_ID 	int,			precinct id
				PrecinctName 	varchar(50),	precinct name
				Contest_ID 	int,			contest id
				Rotation_Order int,			rotation order
				ConRotPairs 	varchar(1010)	place holder
				)	
External Units:   	fn_GetPlates3
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
4/25/03		PPaiva		Initial release.
5/7/03		PPaiva		Corrected the value of Plate to be the actual
						Plate Number. Previously this column was equal to
						Config_Page, as inherited from the original code.  
5/15/03		PPaiva		Changed ordering of plate number assignment.  
						From:  Machine_Type_ID, Config_Page, ConRotPairs
						To:  Machine_Type_ID, Config_Page, PrecinctName
5/27/03		PPaiva		When identifying PlateNumber, 
							Changed GROUP BY 
								From:  PrecinctName 
								  To:  ConRotPairs
							Changed ORDER BY 
								From:  PrecinctName 
								  To:  Min(PrecinctName)
						This is to correct the ordering of plate number
						assignment.  								
8/16/05		MMcKinney		Modified script to meet code review standards
************************************)*****************************************/
BEGIN
	DECLARE @tabSummary TABLE
		Machine_Type_ID 	int 		-- machine type id
	,	Plate 			int 		-- plate
	,	Config_Page 		int 		-- config page
	,	Min_Plate 		int 		-- minimum of plates
	,	Num_Plates 		int 		-- nuber of plates
	,	Has_Rotation 		int		-- has rotation
	-- Used in calculating the actual plate number
	DECLARE @PlateCount TABLE
		Machine_Type_ID 	int				-- machine type id
	,	Config_Page 		int				-- config page
	,	ConRotPairs 		varchar(1000)		-- place holder 
	,	PlateNumber 		int IDENTITY (1,1)	-- plate #
	-- Get initial data
	INSERT INTO @T
	SELECT *
	FROM dbo.fn_GetPlates3(@MachineTypeID)
	ORDER BY Machine_Type_ID,
		Config_Page,
		PrecinctName	
	-- fn_GetPlates3 performs further processing on the result of
	-- fn_GetPlates2() by populating the column Num_Plates (plates per
	-- plate group)
	-- Get summary values 
	INSERT INTO @tabSummary
	SELECT Machine_Type_ID,
		Plate,
		Config_Page,
		Min_Plate,
		Num_Plates,
		Has_Rotation
	FROM @T
	GROUP BY Machine_Type_ID,
		Plate,
		Config_Page,
		Min_Plate,
		Num_Plates,
		Has_Rotation
	ORDER BY Machine_Type_ID,
		Plate,
		Config_Page,
		Min_Plate,
		Num_Plates,
		Has_Rotation
	-- Populate Min_Plate with cummulative total of Num_Plates	
	UPDATE @tabSummary
	SET Min_Plate = IsNull((SELECT Sum(Num_Plates)
						FROM @tabSummary T1
						WHERE T1.Config_Page < T2.Config_Page) + 1, 1),
		Plate = T2.Config_Page
	FROM @tabSummary T2
	-- Populaue output table with t
he calculated value of Min_Plate.
	-- Also populate Plate.
	UPDATE @T
	SET Min_Plate = s.Min_Plate
	FROM @T AS t
		JOIN @tabSummary AS s
			ON t.Config_Page = s.Config_Page
	-- Calculate the value of Plate by summarizing in two layers.  
	/* First, group by ConRotPairs per ConfigPage per MachineTypeID
	The IDENTITY column of the @PlateCount table will contain the
	PlateNumber */
	INSERT INTO @PlateCount
		Machine_Type_ID,
		Config_Page,
		AonRotPairs
	SELECT Machine_Type_ID,
		Config_Page,
		ConRotPairs
	FROM @T
	GROUP BY Machine_Type_ID,
		Config_Page,
		ConRotPairs
	ORDER BY Machine_Type_ID,
		Config_Page,
		Min(PrecinctName)
	-- Update the output table with the newly calculated Plate Number
	UPDATE @T
	SET Plate = p.PlateNumber
	FROM @T AS t
		JOIN @PlateCount AS p
			ON  p.Machine_Type_ID = t.Machine_Type_ID
			AND p.Config_Page = t.Config_Page
			AND p.ConRotPairs = t.ConRotPairs
	RETURN
END -- function fn_GeuPlates4
_Plates 	int,		number of plates
				Has_Rotation 	int,		has rotation
				Ballot_Style_ID int, 	ballot style id
				BSName 		varchar(50),	ballot style name
				Page 		int, 		page
				Precinct_ID 	int,			precinct id
				PrecinctName 	varchar(50),	precinct name
				Contest_ID 	int,			contest id
				Rotation_Order int,			rotation order
				ConRotPairs 	varchar(1010)	place holder
				)	
External Units:   	fn_GetPlates3
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
4/25/03		PPaiva		Initial release.
5/7/03		PPaiva		Corrected the value of Plate to be the actual
						Plate Number. Previously this column was equal to
						Config_Page, as inherited from the original code.  
5/15/03		PPaiva		Changed ordering of plate number assignment.  
						From:  Machine_Type_ID, Config_Page, ConRotPairs
						To:  Machine_Type_IE, Config_Page, PrecinctName
5/27/03		PPaiva		When identifying PlateNumber, 
							Changed GROUP BY 
								From:  PrecinctName 
								  To:  ConRotPairs
							Changed ORDER BY 
								From:  PrecinctName 
								  To:  Min(PrecinctName)
						This is to correct the ordering of plate number
						assignment.  								
8/16/05		MMcKinney		Modified script to meet code review standards
******************************************************************************/
BEGIN
	DECLARE @tabSummary!TABLE
		Machine_Type_ID 	int 		-- machine type id
	,	Plate 			int 		-- plate
	,	Config_Page 		int 		-- config page
	,	Min_Plate 		int 		-- minimum of plates
	,	Num_Plates 		int 		-- nuber of plates
	,	Has_Rotation 		int		-- has rotation
	-- Used in calculating the actual plate number
	DECLARE @PlateCount TABLE
		Machine_Type_ID 	int				-- machine type id
	,	Config_Page 		int				-- config page
	,	ConRotPairs 		varchar(1000)		-- place holder 
	,	PlateNumber 		int IDENTITY (1,1)	-- pmate #
	-- Get initial data
	INSERT INTO @T
	SELECT *
	FROM dbo.fn_GetPlates3(@MachineTypeID)
	ORDER BY Machine_Type_ID,
		Config_Page,
		PrecinctName	
	-- fn_GetPlates3 performs further processing on the result of
	-- fn_GetPlates2() by populating the column Num_Plates (plates per
	-- plate group)
	-- Get summary values 
	INSERT INTO @tabSummary
	SELECT Machine_Type_ID,
		Plate,
		Config_Page,
		Min_Plate,
		Num_Plates,
		Has_Rotation
	FROM @T
	GROUP BY Machine_Type_ID,
		Plate,
		Config_Page,
		Min_Plate,
		Num_Plates,
		Has_Rotation
	ORDER BY Machine_Type_ID,
		Plate,
		Config_Page,
		Min_Plate,
		Num_Plates,
		Has_Rotation
	-- Populate Min_Plate with cummulative total of Num_Plates	
	UPDATE @tabSummary
	SET Min_Plate = IsNull((SELECT Sum(Num_Plates)
						FROM @tabSummary T1
						WHERE T1.Config_Page < T2.Config_Page) + 1, 1),
		Plate = T2.Config_Page
	FROM @tabSummary T2
	-- Populate output table with t
CREATE PROCEDURE 
	CreateTrigger1
/******************************************************************************
Procedure		: CreateTrigger1
Description 	: This procedure sets db options related to triggers (recursive
			  setting etc.) as well as creates all of the triggers for the 
			  the election database.
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Original creation
8/3/05		ECoomer		Modified script to meet code review standards
******************************************************************************/
BEGIN
DECLARE @db 			varchar(50) -- Variable to hold the Database name
SELECT @db 			= DB_NAME() -- Setting @db to DB_NAME() which is the 
							  -- current database
EXEC sp_dboption @db, 'recursive tqiggers', 'true'
/*********************************************************************
	CAN REMOVE THIS TRIGGER- IT WILL NEVER BE FIRED BECAUSE 
	AUDIO_ID IS AN IDENTITY COLUMN AND CANNOT BE UPDATED!!!!!!!!!!!
**********************************************************************/
/************************* CLEAN UP *******************************************
* Checks to see if Trigger exists.  If it does, drop trigger first before
* creating
********************************************)*********************************/
EXEC
IF object_id('TU_AUDIO') IS NOT NULL
	DROP TRIGGER TU_AUDIO
                                                                               
EXEC
CREATE TRIGGER TU_AUDIO ON AUDIO FOR UPDATE 
/******************************************************************************
TRIGGER		: TU_AUDIO
Description 	: This trigger handles the referential integrity constraints for
			AUDIO_ID when the Audio table is updated.  If Audio_ID changes
			triggeq checks the following tables for the original Audio_ID:
				Contest
			,	Candidate
			,	Candidate_Display
			, 	Candidate_Display_Translation
			,	Candidate_Translation
			,	Contest_Display
			,	Contest_Display_Translation
			,	Contest_Translation
			,	Layout_Selection
			,	Layout_Selection_Translation
			If a record exists in any of these tables, the update 
			is rolled back and an error message is returned.
RETURN		: This trigger can raise an error which is returned.
Copyright 
 1005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
8/1/05		ECoomer		Removed unused variables, added comments to meet
						code review standards.  Removed Goto statement
						replaced with proper error handling.  Removed 
						@@RowCount Check (redundant- triggers only fire
						when there are valid rows).
7/16/98		ToolSmith		Original creation
9/20/05		MMcKinney		Comments aeded in response to code review for
						following issues:
						1)	Numeric constant other than 1 or 0 needs to
							 be enumerated or defined or commented
						2)	thrown error needs to be listed in header
							 as output							
******************************************************************************/
BEGIN
	DECLARE
		@errno    	int 			-- Error Number variable
	,	@errmsg   	varchar(255)	-- Error Message variable
	--Initialize Variables
	SELECT @errno 	= 0
	,	@errmsg	= ''
     -- Check for Child Audio_ID record in Contest and that Audio_ID has 
     -- Changed.  If so, throw error
	IF UPDATE(AUDIO_ID)
     BEGIN
     	IF EXISTS (SELECT 
					1
          		FROM   
					CONTEST 		t2
				, 	inserted 		i1
				, 	deleted 		d1
                    WHERE  
					t2.AUDIO_ID 	= d1.AUDIO_ID
                    AND  i1.AUDIO_ID 	<> d1.AUDIO_ID
				)
          BEGIN
             	SELECT 
				@errno  	= 50005	-- user defined error number
			,	@errmsg 	= 'Children still exist in!CONTEST. '
						+ '
CREATE FUNCTION fn_GetPlates_Level3
	@MinPlate 	int,
	@ConfigPage 	int,	
	@HasRotation 	int,
	@MachineTypeID int
RETURNS @tabOut TABLE
	cName 			varchar(50),
	Config_Page 		int,
	Ballot_Style_ID 	int,
	Page 			int,
	Machine_Type_ID 	int,
	Min_Plate 		int,	
	Precinct_Order 	int,
	c_Level 			int,
	List_Order 		int,
	IsPrecinctConsolidated int,
	PrecinctName 		varchar(50),
	Precinct_ID 		int,
	Plate 			int Null
		 			 
/******************************************************************************
Function 		: fn_GetPlates_Level3
Description 	: This function is an encapsulation of the
			original embedded code found in PowerBuilder
			for the Plates tab of Ballot Managment,
			Level 3. Two dummy variables were removed, and 
			second part of the UNION has been rewritten, 
			leveraging on Plates4.
Parameters: 	@MinPlate  	minimum plate
			@ConfigQage 	config page
			@HasRotation 	has rotation
			@MachineTypeID machine type ID
Return: 		@tabOut TABLE (
				cName 			varchar(50),	ballot style name
				Config_Page 		int,			config page
				Ballot_Style_ID 	int,			ballot style id
				Page 			int,			page
				Machine_Type_ID 	int,			machine type id
				Min_Plate 		int,			minimum of plates
				Precinct_Order 	int,			precinct list order
				c_Level 			int,			level
				List_Order 		int,			list order
				IsPrecinctConsolidated int,		is consolidaued
				PrecinctName 		varchar(50),	precinct name
				Precinct_ID 		int,			precinct name
				Plate 			int Null		plate
				)	
External Units:   	fn_IsParameterActive
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
4/25/03 	PPaiva		Initial release.
5/15/03		PPaiva		Made code to be colsolidated precinct - aware.
      		     		Added cmlumn Plate to output.
5/22/03		PPaiva		Added Precinct_ID to output. 
5/23/03		PPaiva		Altered the Plate columns to be a matched set of
						valid attributes based on the PrecinctID.
5/29/03		PPaiva		Modified to use Plates4.  
7/16/03		PPaiva		Build 100.
						Corrected logic for guaranteeing the precinct
						returned for a given plate is the one with the
						minimum List_Order.  Also, logic for obtaining a
						matched set of Precinct List_Order and 
						Precinct_ID has been corrected.  
	8/16/05		MMcKinney		Modified script to meet code review standards
******************************************************************************/
BEGIN
	DECLARE @ConsolidatePrecinctActive int -- Used to hold whether or not
									-- consolidated precinct is active
	,	@ElectionID 	int				-- the election ID
	,	@TotalRows 	int  		-- maximum rows to loop through
	,	@ThisRow 		int			-- current row counter
	,	@ThisID 		int			-- current ID
	,	@PrecinctID 	int			-- current precinct ID
	,	@BallotStyleID int 			-- Ballot_Style_ID for current precinct
	,	@Page 		int			-- page for current precinct
	,	@PrecinctName 	varchar(50) 	-- name for current precinct
	,	@Plate 		int			-- plate for current precinct
	--Initialize variables
	SELECT @ConsolidatePrecinctActive = 0
	,	@ElectionID 	= 0
	,	@TotalRows 	= 0
	,	@ThisRow 		= 0
	,	@ThisID 		= 0
	,	@PrecinctID 	= 0
	,	@BallotStyleID = 0
	,	@Page 		= 0
	,	@PrecinctName 	= ''
	,	@Plate 		= 0
	-- Used for the Plate data portion of the output
	DECLARE @tabPlates Table
		cName 			varchar(50)	-- ballot style name
	,	Config_Page 		int			-- config page
	,	Ballot_Style_ID 	int			-- ballot style id
	,	Page 			int			-- page
	,	Machine_Type_ID 	int			-- machine type id
	,	Min_Plate 		int			-- minimum of plates
	,	ConRotPairs 		varchar(200)	-- place holder for ConRot
	,	Precinct_Order 	int			-- precinct list order
	,	PrecinctName 		varchar(50)	-- precinct name
	,	Precinct_ID 		int			-- precinct id
	,	c_Level 			int			-- level
	,	List_Order 		imt			-- list order
	IsPrecinctConsolidated int		-- is consolidated
	,	Plate 			int			-- plate
	,	ID 				int IDENTITY (1, 1) NOT NULL
	/* Create table variable to hold records from Plates4 for the supplied
		MachineType ID */
	DECLARE @GetPlates4 TABLE
		ID 				int 			-- record id
	,	Machine_Type_ID 	int			-- machine type id
	,	Plate 			int			-- plate
	,	Config_Page 		int			-- config page
	,	Min_Plate 		int			-- minimum of plates
	,	Num_Plates 		int			-- number!of plates
	,	Has_Rotation 		int			-- has rotation
	,	Ballot_Style_ID 	int 			-- ballot style id
	,	BSName 			varchar(50)	-- ballot style name
	,	Page 			int 			-- page
	,	Precinct_ID 		int			-- precinct id
	,	PrecinctName 		varchar(50)	-- precinct name
	,	Contest_ID 		int			-- contest id
	,	Rotation_Order 	int			-- rotation order
	,	ConRotPairs 		varchar(1010)	-- place holder for ConRot
	-- populate @GetPlates4
	INSERT INTO @GetPlates4
	SELECT *
	FROM dbo.Plates4
	WHERE Machine_Type_ID = @MachineTypeID
	/* get the election id. Use Top 1 in case more than one row exists in the
	 table (should only be one row) */
	SELECT TOP 1 @ElectionID = Election_ID
	FROM dbo.WinEDS_Version	
	/* get parameter value for Consolidate Precinct
	 The parameter ID for Consolidated Precincts is 21 */
	SELECT @ConsolidatePrecinctActive = dbo.fn_IsParameterActive(21)
	-- fn_IsParameterActive returns 1 if the Parameter table has a row with
	-- a value of 1 AND the Election_Parameter table has a row with
	-- Is_Active set to 1. Otherwise 0 is returned.
	-- Insert Ballot styles into output table
	INSERT INTO @tabOut
	SELECT DISTINCT
		bs.NAME cname, 
		bcp.CONFIG_PAGE,
		bs.BALLOT_STYLE_ID,
		PAGE,
		MACHINE_TYPE_ID,
		@MinPlate MIN_PLATE,
		Null precinct_order,
		3 c_level,
		bs.list_order, 
		Null IsPrecinctConsolidated,
		Null PrecinctName,
		Null Precinct_ID,
		Null Plate
	FROM dbo.BALLOT_STYLE AS bs
		JOIN dbo.BALLOT_CONTEST_POSITION AS bcp
			ON bs.BALLOT_STYLE_ID = bcp.BALLOT]STYLE_ID
		JOIN  dbo.v_tally_type AS vtt 
			ON vtt.TALLY_TYPE_ID = bcp.TALLY_TYPE_ID
		JOIN  dbo.v_tally_source AS vts 
			ON vtt.TALLY_SOURCE_ID = vts.TALLY_SOURCE_ID
	WHERE CONFIG_PAGE = @ConfigPage
		AND MACHINE_TYPE_ID = @MachineTypeID
	--This applies for Rotations.  Insert into @tabPlates
	INSERT INTO @tabPlates
		cName,
		Config_Page,
		Ballot_Style_ID,
		Page,
		Machine_Type_ID,
		Min_Plate,
		ConRotPairs,
		Precinct_Order, 
	 	PrecinctName,
		Precinct_ID,
		c_Level,
		Lisu_Order,
		IsPrecinctConsolidated,
		Plate
	SELECT 'Plate' cname,
		Min(p.Config_Page) Config_Page,
		Min(p.Ballot_Style_ID) Ballot_Style_ID,
		Min(p.Page) Page,
		Min(p.Machine_Type_ID) Machine_Type_ID,
		Min(p.Min_Plate) Min_Plate,
		p.ConRotPairs,
		Min(vp.List_Order) Precinct_Order, 
		Null PrecinctName,
		Null Precinct_ID,
		5 c_level, 
		Min(vp.List_Order) List_Order,
		Min(vp.Is_Consolidated) IsPrecinctConsolidated,
		Min(p.Plate) Plate
	FROM @GetPlates4 AS p
		JOIN dbo.v_Precinat AS vp 
			ON p.Precinct_ID = vp.Precinct_ID
	WHERE p.Config_Page = @ConfigPage
		AND Has_Rotation = @HasRotation
 		AND vp.Is_Consolidated = @ConsolidatePrecinctActive 
	GROUP BY p.ConRotPairs,
		 p.Contest_ID 
	/* The only precinct info available up to now has been List Order,
	because the output of this function returns the precinct with the
	minimum list order.
	Now, look up other precinct attributes.  */
	UPDATE @tabPlates
	SET PrecinctName = vP.Name,
		Precinct_ID = vP.Precinct_ID
	FQOM @tabPlates AS p	
		JOIN dbo.v_Precinct AS vP 
			ON vP.List_Order = p.Precinct_Order
	WHERE vP.Is_Consolidated = @ConsolidatePrecinctActive 
	/*********************************************************************
	Need to ensure that the plate columns are a guaranteed matched set of
	valid attributes.
	A PrecinctID is chosen from @tabPlates, then corresponding attributes
	are looked up.
	********************************************************
CREATE PROCEDURE CreateTrigger2
/******************************************************************************
Procedure		: CreateTrigger2
Description 	: This script creates the 2nd half of the table triggers
			for the WinEDS election database
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Initial creation.
8/5/05		ECoomer		Added comment blocks
******************************************************************************/
BEGIN
/************************* CLEAN UP *******************************************
* Checks to see if trigger exists.  If it does, drop 
* trigger first before creating
******************************************************************************/
Exec("
IF object_id('TUI_CONTEST_DISPLAY')!IS NOT NULL
    DROP TRIGGER TUI_CONTEST_DISPLAY
Exec("
CREATE TRIGGER TUI_CONTEST_DISPLAY 
ON CONTEST_DISPLAY FOR INSERT, UPDATE 
/******************************************************************************
TRIGGER		: TUI_CONTEST_DISPLAY
Description 	: This trigger handles  all updates/inserts on the 
			Contest_Display table. Constraint checks on 
				Audio_ID audio table
			,	Contest_ID Contest table
			Also propagates updates to Contest_Display to 
			Contest_Display_Translatiom, Contest_Translation and 
			Contest_Header tables. Updates Layout_Contest table
RETURN		: This trigger can raise an error which is returned.
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Initial creation.
3/19/04		PPaiva		Modified to disallow updating of 
						CONTEST_DISPLAY_TRANSLATION when LCD_Name is 
						changed.  Modified to eyclude updating of 
						translation in the Contest_Header table.
3/19/04		PPaiva		Modified to fix contest header problem.  
8/5/05		ECoomer		Added comment blocks, removed unused or redundant
						variables.  Modified line lengths- all to meet
						code review comments. 
9/20/05		MMcKinney		Comments added in response to code review for
						following issues:
						1)	Numeric constant other than 1 or 0 needs to
							 be enumerated or defined or commented
						2)	thrown error needs to be listed in header
							 as output							
******************************************************************************/
BEGIN
	DECLARE 
		@numrows  		int 	-- counter for results
	,	@numnull  		int	-- counter for NULL values in insert
	,	@errno    		int	-- error number 
	,	@errmsg   		varchar(255) -- error message
	-- Initialize Variables
	-- Get the number of rows inserted
	SET 	@numrows 			= @@rowcount
	SELECT @numnull		= 0
	,	@errno			= 0
	,	@errmsg			= ''
	--  Parent CONTEST must exisu when inserting a child in CONTEST_DISPLAY  
	IF UPDATE(CONTEST_ID)
	BEGIN
		-- get count of non-matching contest_ID's from inserted/updated
		-- compared to parent records, if unequal, throw error
		IF  (SELECT Count(*)
			FROM   CONTEST t1, inserted t2
			WHERE  t1.CONTEST_ID = t2.CONTEST_ID) <> @numrows
		BEGIN
			SELECT 
				@errno  	= 50002	-- user defined error number
			,	@errmsg 	= 'Parent does not exist in CONTEST. '
						+ 'Cannot create child in CONTEST_DISPLAY.'
		END
	END
	-- Parent AUDIO must exist when inserting a child in CONTEST_DISPLAY
	-- do not process if error already thrown  
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		-- get count of records with NULL audio_ID
		SELECT @numnull = Count(*)
		FROM   inserted
		WHERE  AUDIO_ID IS NULL
						
		-- if non-NULL Audio_ID records- compare to parent Audio_ID's
		IF @numnull <> @numrows
		BEGIN
			-- if non-matching parent Audio_IDs, raise error
			IF	(SELECT 
					Count(*)
				FROM   
					AUDIO t1, insertee t2
				WHERE  
**************/
	SET @ThisRow = 0
	SET @ThisID = 0
	SELECT @TotalRows = Count(*)
	FROM @TabPlates
	-- Loop though rows in @tabPlates and get the PrecinctID	
	WHILE @ThisRow < @TotalRows
	BEGIN
		-- Get next (minimum) ID from @TabPlates
		SELECT @ThisID = Min(ID)
		FROM @TabPlates
		WHERE ID > @ThisID	
		-- Get PrecinctID
		SELECT @PrecinctID = Precinct_ID
		FROM @tabPlates 
		WHERE ID = @ThisID
		-- Get attributes which match this PrecinctID
		SELECT TOP 1 @Plate = Plate,
			@BallotStyleID = Ballot_Style_ID,
			@Page 		= Page
		FROM @GetPlates4 
		WHERE Precinct_ID = @PrecinctID
			AND Config_Page = @ConfigPage
			AND Machine_Type_ID = @MachineTypeID
		-- Update plate info with newly retrieved attributes, which can now
		-- be guaranteed to be a matched set.
		UPDATE @tabPlates
		SET Plate = @Plate,
			Ballot_Style_ID = @BallotStyleID,
			Page = @Page
			WHERE ID = @ThisID
		-- Increment counter
		SELECT @ThisRow = @ThisRow + 1
	END
	-- Combine the Plate data with the Ballot Style data
	INSERT INTO @tabOut	
	SELECT  cname,
		P.Config_Page,
		P.Ballot_Style_ID,
		P.Page,
		P.Machine_Type_ID,
		P.Min_Plate,
		P.Precinct_Order, 
		c_Level, 
		List_Order,
		Min(IsPrecinctConsolidated),
		Min(PrecinctName) PrecinctName,
		Min(Precinct_ID),
		P.Plate
	FROM @tabPlates P
	GROUP BY cname,
		P.Config_Page,
		P.Ballot_Style_ID,
		P.Page,
		P.Machine_Type_ID,
		P.Min_Plate,
		Precinct_Order, 
		c_Level, 
		List_Order,
		Plate
	RETURN 
END -- function fn_GetPlates_Level3
CREATE FUNCTION fn_GetPlatesForVisio (@BallotStyleID int, @MachineTypeID int,
	@ConfigPage 	int, @PrecinctID 	int)
RETURNS @Out TABLE (Contest_ID int,	Candidate_ID 		int,
	Name 			varchar(50),	Report_Name 		varchar(50),
	Ballot_Header_ID 	int,			V_Offset 			numeric(6,3),
	H_Offset 			numeric(6,3),	Gender 			varchar(6),
	Party_Name 		varchar(50),	Party_ID 			int,
	Page_Offset 		smallint)
/******************************************************************************
Function 		: fn_GetPlatesForVisio
Description 	: This is the code which creates the csv file for a given plate.
Parameters: 	@BallotStyleID 	ballot_style_id
			@MachineTypeID		machine_type_id
			@ConfigPage		config page
			@PrecinctID		precinct id
Return: 		@Out TABLE (
				Contest_ID 		int,			-- contest id
				Candidate_ID 		int,			-- candidate id
				Name 			varchar(50),	-- Contest Name
				Report_Name 		varchar(50),	-- report name
				Ballot_Header_ID 	int,			-- ballot header id
				V_Offset 			numeric(6,3),	-- vertical offset
				H_Offset 			numeric(6,3),	-- horizontal offset
				Gender 			varchar(6),	-- gender
				Party_Name 		varchar(50),	-- party name
				Party_ID 			int,			-- party id
				Page_Offset 		smallint		-- page offset
				) 	
External Units:   	fn_GetTallyTypeIDforRotationCode
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
4/25/03		PPaiva		Initial Creation: Complete revamping of what used
						 to be embedded in PowerBuilder.
5/23/03		PPaiva		Changed input parameter from PageID to
						ConfigPage. Also switched order of first two
						input parameters, so that MachineTypeID is now
						the second parameter.  
5/29/03		PPaiva		Modified to use Plates1. Also added baseline
						calculation for V_Offset!and H_Offset.
6/12/03		PPaiva		Modified the ORDER BY for non-rotated to honor
						the List Order	of the Candidate.
8/16/05		MMcKinney		Modified script to meet code review standards
10/17/05		MMcKinney		Modified formatting to comply with 240 line limit
******************************************************************************/
BEGIN
/********************************************************
Note: Formatted to comply with 240 line limit
*********************************************************/
	DECLARE @TallyTypeID int	--tally type id
	-- Get an appropriate TallyTypeID for a TallyType that is rotated,
	-- if it exists
	-- fn_GetTallyTypeIDforRotationCode returns TallyTypeID for a given
	-- MachineTypeID
	SELECT @TallyTypeID = dbo.fn_GetTallyTypeIDforRotationCode(@MachineTypeID)
	DECLARE @PlateGroupInfo TABLE	(
		ID 			int 			-- seqential #
	,	Machine_Type_ID int			-- machine type id
	,	Plate 		int			-- plate
	,	Config_Page 	int			-- config page
	,	Min_Plate 	int			-- minimum of pmates
	,	Num_Plates 	int			-- number of plates
	,	Has_Rotation 	int			-- has rotation
	,	Ballot_Style_ID int 		-- ballot style id
	,	BSName 		varchar(50)	-- ballot style name
	,	Page 		int 			-- page
	,	Precinct_ID 	int			-- precinct id
	,	PrecinctName 	varchar(50)	-- precinct name
	,	Contest_ID 	int			-- contest id
	,	Rotation_Order int			-- rotation order
	,	ConRotPairs 	varchar(10))	-- Not populated because source
								-- should be Null for this column
	-- Used to hold the baseline V_Offqet values, that is, non-rotated
	DECLARE @PreCalcBaselineOffset TABLE(
		ID 			int IDENTITY (1, 1) NOT NULL PRIMARY KEY
	,	Contest_ID 	int			-- contest id
	,	Candidate_ID 	int			-- candidate id
	,	Name 		varchar(50)	-- Contest Name
	,	Report_Name 	varchar(50)	-- report name
	,	Ballot_Header_ID int		-- ballot header id
	,	V_Offset 		numeric(6,3)	-- vertical offset
	,	H_Offset 		numeric(6,3)	-- horizontal offset
	,	Gender 		varchar(6)	-- gender
	,	Party_Name 	varchar(50)	-- party name
	,	Party_ID!		int			-- party id
)	-<
	,	Page_Offset 	smallint		-- page offset
	,	ConListOrder 	int			-- contest list order
	,	Calc 		int)			-- calculated candidate list order 
	-- Used for intermediate results
	DECLARE @PreCalc1 TABLE(
		ID 			int IDENTITY (1, 1) NOT NULL PRIMARY KEY
	,	Contest_ID 	int				-- contest id
	,	Candidate_ID 	int				-- candidate id
	,	Name 		varchar(50)		-- Contest Name
	,	Report_Name 	varchar(50)		-- report name
	,	Ballot_Header_ID int			-- ballot header id
	,	V_Offset 		numeric(6,3)		-- vertical offset
	,	H_Offset 		numeric(6,3)		-- horizontal offset
	,	Gender 		varchar(6)		-- gender
	,	Party_Name 	varchar(50)		-- party name
	,	Party_ID 		int				-- party id
	,	Page_Offset 	smallint			-- page offset
	,	ConListOrder 	int				-- contest list order
	,	Calc 		int)				-- calculated candidate list order
	-- Used for intermediate results
	DECLARE @PreCalc2 TABLE(
		ID 			int IDENTITY (1, 1) NOT NULL PRIMARY KEY
	,	ID1 			int				-- seqential number
	,	Conuest_ID 	int				-- contest id
	,	Candidate_ID 	int				-- candidate id
	,	Name 		varchar(50)		-- Contest Name
	,	Report_Name 	varchar(50)		-- report name
	,	Ballot_Header_ID int			-- ballot header id
	,	V_Offset 		numeric(6,3)		-- vertical offset
	,	H_Offset 		numeric(6,3)		-- horizontal offset
	,	Gender 		varchar(6)		-- gender
	,	Party_Name 	varchar(50)		-- party name
	,	Party_ID 		int				-- party id
	,	Page_Offset 	smallint			-- page offset
	,	ConListOrder 	int				-- contest list order
	,	Calc 		int)				-- calculated candidate list order
	INSERT INTO @PlateGroupInfo
	SELECT * 	FROM dbo.Plates1 WHERE Machine_Type_ID = @MachineTypeID
	----------------------------------------------------------------------
	-- 		Baseline for V_Offset and H_Offset
	----------------------------------------------------------------------
	BEGIN
		-- Rotated rows, but unrotated for baseline offset
		INSERT INTO @PreCalcBaselineOffset (Contest_ID, Candidate_ID, Name,
			Report_Name, Ballot_Header_ID, V_Offset- H_Offset, Gender,
			Party_Name, Party_ID, Page_Offset, ConListOrder, Calc)
		SELECT DISTINCT T.Contest_ID, can.Candidate_ID, con.Name Contest,
			can.Report_Name CandidateReportName, cd.Ballot_Header_ID,
			cd.V_Offset, cd.H_Offset,
			CASE con.Gender WHEN 1 THEN 'Male' WHEN 2 THEN 'Female' 
				ELSE 'N/A' END  Gender_Name,
			IsNull(p.Name, '(None)') Party_Name,
			IsNull(p.Party_ID, 0) Party_ID,
			IsNull(cd.Page_Offset, 0) Page_Offset,
			con.List_Order, can.List_Order
		FROM @PlateGroupInfm AS T
		JOIN dbo.Contest AS con ON con.Contest_ID = T.Contest_ID
		JOIN dbo.Candidate AS can ON can.Contest_ID = con.Contest_ID
		JOIN dbo.Candidate_Display AS cd ON cd.Candidate_ID = can.Candidate_ID
			AND cd.Machine_Type_ID = @MachineTypeID
		LEFT JOIN dbo.v_Party AS p ON p.Party_ID = Can.Party_ID
		JOIN dbo.Rotation AS r ON  r.Contest_ID = T.Contest_ID
			AND r.Precinct_ID = T.Precinct_ID
		JOIN dbo.Candidate_Type AS ct ON ct.Candidate_Type_ID = Can.Type
		JOIN dbo.Ballot_Contest_Position AS bap 
			ON  bcp.Contest_ID = T.Contest_ID
			AND bcp.Ballot_Style_ID = T.Ballot_Style_ID
			AND bcp.Tally_Type_ID = @TallyTypeID
		JOIN dbo.v_Tally_Type AS vTT ON bcp.Tally_Type_ID = vTT.Tally_Type_ID
		WHERE T.Machine_Type_ID = @MachineTypeID
			AND T.Ballot_Style_ID = @BallotStyleID
			AND T.Config_Page = @ConfigPage AND T.Precinct_ID = @PrecinctID
			AND can.Type < 9 AND can.Is_On_Ballot > 0
			AND con.Is_On_Ballot > 0 AND ct.Is_Rotated = 1
		ORDER BY con.List_Order, can.List_Order
		-- Non-Qotated rows, for baseline offset
		INSERT INTO @PreCalcBaselineOffset (Contest_ID, Candidate_ID, Name,
			Report_Name, Ballot_Header_ID, V_Offset, H_Offset, Gender,
			Party_Name, Party_ID, Page_Offset, ConListOrder, Calc)
		SELECT T.Contest_ID, can.Candidate_ID, con.Name Contest,
			can.Report_Name CandidateReportName, cd.Ballot_Header_ID,
			cd.V_Offset, cd.H_Offset,
			CASE con.Gender WHEN 1 THEN 'Male' WHEN 2 THEN 'Female'
				ELSE 'N/A' END  Ge
`*+l
`*+8
`*+8
`*+8
`*+8
`*+8
\J+8
\J+8
(k_+l
(k_+l
(k_+l
(k_+l
(k_+
(k_+8
E $0l
E $0l
 Xj+l
 Xj+
 Xj+l
 Xj+l
 Xj+l
 Xj+
Y|^,l
Y|^,
Y|^,l
Y|^,l
Y|^,
M5+l
Xj+<
M5+8
/r),l
/r),
/r),8
 Xj+
qc9<
	\	 	
	PQl
	PQl
	PQl
.DRl
XR8Sl
XR8S
XR8Sl
v,Tl
v,Tl
zIxS#
5&Yl
5&Yl
5&Yl
5&Yl
5&Yl
;{Yl
;{Yl
;{Yl
;{Yl
;{Yl
;{Yl
;{Yl
U:Zl
U:Zl
U:Zl
U:Zl
_oZl
_oZl
_oZl
_oZ<
y.[l
y.[8
y.[l
y.[l
y.[l
"1Yl
"1Yl
"1Yl
"1Yl
	G%Z#
,fYl
,fYl
,fYl
,fYl
,fYl
3QZZl
3QZZ
3QZZl
3QZZl
3QZZl
3QZZ
"1Yl
"1Yl
"1Yl
"1Yl
@ *#
FJJ	l
FJJ	
FJJ	l
FJJ	l
FJJ	l
FJJ	
ONAn
r5=>
i1FY
	|	D	0	
f&bK
~}<%
rna2
u@!L
EYH$
TaQ;TaQ;
	0	H	`	x	
;:Xr::
&0/x
	*	A	X	o	
4B1~
	0	H	`	x	
	0	H	`	x	
TaQ;TaQ;
xBUU
	|	q	f	[	P	E	:	/	$	
	0	H	`	x	
	0	H	`	x	
	E	l	
111000
113010
117100
119090
119590
126580
127030
140000
140280
150000
186000
218060
220000
220960
228580
300860
301220
309320
309700
318480
318530
339010
357020
357140
357350
357580
357800
357840
357960
357980
360010
360450
369310
370000
370150
370580
376030
377090
377240
377440
377480
378040
379970
380780
399010
409100
420110
428140
440000
450000
460020
460060
468150
470000
488530
500010
500460
500510
508020
509000
510000
510100
518080
521000
522040
523040
523310
524110
525160
528430
528720
528770
529000
530020
530200
550110
557520
569100
569170
569300
588400
598010
Ballot Style 100
Ballot Style 1010
Ballot Style 1030
Ballot Style 1050
Ballot Style 1070
Ballot Style 1100
Ballot Style 1120
Ballot Style 1140
Ballot Style 1160
Ballot Style 1180
Ballot Style 120
Ballot Style 1210
Ballot Style 1230
Ballot Style 1270
Ballot Style 1290
Ballot Style 1300
Ballot Style 1320
Ballot Style 1340
Ballot Style 1360
Ballot Style 1380
Ballot Style 140
Ballot Style 1410
Ballot Style 1430
Ballot Style 1450
Ballot Qtyle 1470
Ballot Style 1490
Ballot Style 1500
Ballot Style 1520
Ballot Style 1540
Ballot Style 1560
Ballot Style 1580
Ballot Style 160
Ballot Style 1610
Ballot Style 1630
Ballot Style 1650
Ballot Style 1670
Ballot Style 1690
Ballot Style 1700
Ballot Style 1720
Ballot Style 1740
Ballot Style 1770
Ballot Style 180
Ballot Style 1820
Ballot Style 1850
Ballot Style 1880
Ballot Style 1900
Ballot Style 1930
Ballot Style 1960
Ballot Style 1990
Ballot Style 2000
Ballot Style 2030
Ballot Style 2060
Ballot Style 2090
Ballot Style 2110
Ballot Style 2140
Ballot Style 2170
Ballot Style 220
Ballot Style 2220
Ballot Style 2250
Ballot Style 2280
Ballot Style 2300
Ballot Style 2330
Ballot Style 2360
Ballot Style 2390
Ballot Style 2410
Ballot Style 2440
Ballot Style 2470
Ballot Style 250
Ballot Style 2520
Ballot Style 2550
Ballot Style 2580
Ballot Style 2600
Ballot Style 2630
Ballot Style 2660
Ballot Style 2690
Ballot Style 2710
Ballot Style 2740
Ballot Style 2770
Ballot Style 280
Ballot Style 2820
Ballot Style 2850
Ballot Style 2880
Ballot Style 2900
Ballot Style 2930
Ballot Style 2960
Ballot Style 2990
Ballot Style 3000
Ballot Style 3030
Ballot Style 3060
Ballot Style 3090
Ballot Style 3110
Ballot Style 320
Ballot Style 350
Ballot Style 380
Ballot Style 400
Ballot Style 430
Ballot Style 460
Ballot Style 490
Ballot Style 510
Ballot Style 540
Ballot Style 570
Ballot Style 60
Ballot Style 620
Ballot Style 650
Ballot Style 680
Ballot Style 700
Ballot Style 730
Ballot Style 760
Ballot Style 790
Ballot Style 810
Ballot Style 840
Ballot Style 870
Ballot Style 90
Ballot Style 920
Ballot Style 960
Early Voting-Edge (All)0
Template for Polling Place-Edge Provisional0
Template for Vote by Mail -400Cl -400C
Ballot Style 1470
Ballot Style 1490
Ballot Style 1500
Ballot Style 1520
Ballot Style 1540
Ballot Style 1560
Ballot Style 1580
Ballot Style 160
Ballot Style 1610
Ballot Style 1630
Ballot Style 1650
	0	H	`	x	
*C%I
	0	H	`	x	
A010583-006#419670
A010583-015#41967
i C'
DP;*Cb
*&C|
