
	############### Sorting
	sort_index := {
		if	contains(card.team_full, match: "<word-list-affiliation1></word-list-affiliation1>")	then "2"
		else if	contains(card.card_type, match: "equipment")						then "3"
		else if card.card_type=="location"								then "4"
		else if card.card_type=="plot twist"								then "5"
		else if card.card_type=="planet"								then "6"
		else 												     "1"
	}
	extensive_sort := {
			card.team_full + card.full_name + card.version_full
	}
	rarity_sort := {
		if contains(card.shape, match: "old") then "B"
		else if contains(card.shape, match: "avatar") then "C"
		else if contains(card.shape, match: "alter ego") then "D"
		else "A"
	}
	
	############### Determine Card Position
	pos_of_card := {
		position(
			of: card
			in: set
			order_by: { rarity_sort() + sort_index() + extensive_sort() }
			) + 1
	}
	
	############################################################## Text Filters
	card_shape := { "new" }
	#  - adds all symbols
	#  - bolds keywords
	#  - makes text in parentheses italic
	text_filter := 
		# step 1 : Remove all automatic tags
		tag_remove_rule(tag: "<sym-auto>") +
		tag_remove_rule(tag: "<i-auto>")   +
		tag_remove_rule(tag: "<b-auto>")   +
		remove_tag@(tag: "<nospellcheck") +
		# step 2 : Reminder text for keywords
		expand_keywords@(
			condition: {
				correct_case
			}
			default_expand: {
				chosen(choice:if correct_case then mode else "lower case", set.automatic_reminder_text)
			},
			combine: {
				# un-bold parameters
				keyword := tag_contents(keyword, tag:"<param",
				              contents: {"</b-auto>{input}<b-auto>"})
				reminder := process_english_hints(reminder)
				# the combined result
				"<b-auto>{keyword}</b-auto>"
				 + if expand then "<atom-reminder-{mode}> ({reminder})</atom-reminder-{mode}>"
			}) +
		# step 3 : Expand shortcut words ~ and CARDNAME
		replace_rule(
			match: "~|~THIS~|CARDNAME",
			in_context: "(^|[[:space:]])<match>",
			replace: "<atom-cardname>&</atom-cardname>"
			) +
		# step 4 : Fill in atom fields
		tag_contents_rule(
			tag: "<atom-cardname>",
			contents: { if card.name=="" then "CARDNAME" else card.name }
			) +
		# step 5a: add arrow & diamond symbols
		replace_rule(
			match: "->|>>>|@|<>|•",
			replace: "<sym-auto>&</sym-auto>") +
		# step 7: keyword parameters should not be bolded
		# step 7a: put </b> before each <param>
		#replace@(
		#	match: "<param[^>]*>",
		#	replace: "</b-auto>&") +
		# step 7b: put <b> after each </param>
		#replace@(
		#	match: "</param[^>]*>",
		#	replace: "&<b-auto>") +
		# step 8 : Italic reminder text
		replace_rule(
			match: "[(][^)\n]*[)]?",
			in_context: "(^|[[:space:]])<match>|<atom-keyword><match>",
		 	replace: "<i-auto>&</i-auto>")
	
	############### Word List Scripts for Affiliations and Card Types
	type_over_list := replace_rule(match:" ?-$", replace:"")
	
	affiliation_1_filter :=
		tag_remove_rule(tag: "<word-list-") +
		tag_remove_rule(tag: "<WORD-LIST-AFFILIATION1>") +
		tag_remove_rule(tag: "</WORD-LIST-AFFILIATION1>") +
		type_over_list +
		{ "<word-list-affiliation1>{if contains(card.shape, match: "old") then (input) else to_upper(input)}</word-list-affiliation1>" }
	
	space_to_wltags := replace_rule(match:"( +|<soft> </soft>)",
	                                replace:{"</word-list-{list_type}>{_1}<word-list-{list_type}>"})
	
	affiliation_2_filter :=
		tag_remove_rule(tag: "<word-list-") +
		tag_remove_rule(tag: "<WORD-LIST-AFFILIATION2>") +
		tag_remove_rule(tag: "</WORD-LIST-AFFILIATION2>") +
		type_over_list +
		{ "<word-list-affiliation2>{if contains(card.shape, match: "old") then (input) else to_upper(input)}</word-list-affiliation2>" }
	
	############### Determine type of card
	c_optional_character := filter_rule(match: "Concealed—Optional")
	concealed_character := filter_rule(match: "Concealed")
	keyword_sort_equipment := filter_rule(match: "Transferable")
	keyword_sort_location := filter_rule(match: "Terraform")
	keyword_sort_plot_twist := filter_rule(match: "Ongoing:")
	card_type := {
		if      contains(card.team, match: "Location")		then "location"
		else if contains(card.team, match: "LOCATION")		then "location"
		else if keyword_sort_location(card.rule_text) != ""    	then "location"
		else if card.team=="Planet"				then "planet"
		else if card.team=="PLANET"				then "planet"
		else if contains(card.team, match: "Equipment")		then "equipment visible equipment"
		else if contains(card.team, match: "EQUIPMENT")		then "equipment visible equipment"
		else if keyword_sort_equipment(card.rule_text) != ""   	then "equipment visible equipment"
		else if contains(card.team, match: "Plot Twist")	then "plot twist"
		else if contains(card.team, match: "PLOT TWIST")	then "plot twist"
		else if keyword_sort_plot_twist(card.rule_text) != ""  	then "plot twist"
		else if card.symbols == "ongoing"	        	then "plot twist"
		else if c_optional_character(card.rule_text) != ""	then "characters concealed-optional concealed-optional character"
		else if concealed_character(card.rule_text) != ""	then "characters hidden concealed"
		else							     "characters visible character"
	}
	# Default symbols
	flightrange_detect := { if card.flightrange == "flight" then "flight"
		else if card.flightrange == "range" then "range"
		else if card.flightrange == "both" then "flight, range"
		else ""
	}
	ongoing_detect := {
		if	keyword_sort_plot_twist(card.rule_text) != ""   then "ongoing"
		else ""
	} 
	symbol_default := { flightrange_detect() + (if flightrange_detect() != "" then ", " else " ") + ongoing_detect() }

	# Default 'team' name of card
	team := {
		if      is_location()   then "Location"
		else if is_equipment()  then "Equipment"
		else if is_plot_twist() then "Plot Twist"
		else                         ""
	}
	true_pass := {
		if	is_character() then false else true
	}
	
	############### Type of card
	
	is_dual := {
		card.card_type == "characters visible character dual" or
	        card.card_type == "characters hidden concealed dual" or
	        card.card_type == "characters concealed-optional concealed-optional dual"
	}
	is_new_dual := {
		card.card_type == "characters visible character dual (new)" or
	        card.card_type == "characters hidden concealed dual (new)" or
	        card.card_type == "characters concealed-optional concealed-optional dual (new)"
	}
	is_not_new_dual := {
		card.card_type == "characters visible character" or
	        card.card_type == "characters visible character dual" or
	        card.card_type == "characters hidden character concealed" or
	        card.card_type == "characters hidden character concealed dual" or
		card.card_type == "characters concealed-optional concealed-optional character" or
	        card.card_type == "characters concealed-optional concealed-optional dual"
	}
	is_character := { contains(card.card_type, match: "characters")
	}
	is_concealed_optional := { contains(card.card_type, match: "concealed-optional") or
		contains(card.rule_text, match: "Concealed—Optional")
	}
	is_concealed := { contains(card.card_type, match: "hidden") or
		contains(card.rule_text, match: "Concealed")
	}
	is_equipment := { contains(card.card_type, match: "equipment")
	}
	is_location := {
		card.card_type == "location"
	}
	is_plot_twist := {
		card.card_type == "plot twist"
	}
	is_ch_or_eq := {
		is_character() or is_equipment()
	}
	is_ch_or_pt := {
		is_character() or is_plot_twist()
	}
	############### Watermark Scripts
	
	watermark_narrow := {
		card.watermark == "Marvel A-C Brood" or
		card.watermark == "Marvel A-C Brotherhood" or
		card.watermark == "Marvel D-H Hellfire Club" or
		card.watermark == "DC A-C Anti-Matter" or
		card.watermark == "DC A-C Arkham Inmates" or
		card.watermark == "DC N-S Shadowpact"
	}
	watermark_wide := {
		card.watermark == "Marvel D-H Horsemen of Apocalypse" or
		card.watermark == "DC I-M JLA" or
		card.watermark == "DC I-M JSA"
	}

	############### Additional Scripts
	
	only_numbers := filter_text@(match: "^[0123456789]+")

	word_count := break_text@(match:"[^[:space:]]+") + length
	
	name_sep := {
		if contains(set.logo, match: "Marvel") then (
			if is_character() and card.identity=="" then "™"
			else if is_character() and card.identity!="" then "™ <sym>•</sym> "
			else if is_equipment() and card.identity=="" then " "
			else if is_equipment() and card.identity!="" then " <sym>•</sym> "
			else ""
		)
		else if is_character() and card.identity=="" then " "
		else if is_character() and card.identity!="" then " <sym>•</sym> "
		else if is_equipment() and card.identity=="" then " "
		else if is_equipment() and card.identity!="" then " <sym>•</sym> "
		else " "
	}
	
	separator_type := {
		if contains(card.shape, match:"old") then (
			if team2 != "<word-list-affiliation2></word-list-affiliation2>" then " <sym>•</sym> "
			else " "
		)
		else " • "
	}
	
	only_first := replace@(match:"card.team", replace:"")
	
	all_affiliations := {
		for each card in set do
			if is_character() then "," + only_first(to_text(card.team))
	}
	