content: property pScriptTitle : "Sente 6 Notes to Devonthink"
  property pVer : ".073"
  property pTitle : pScriptTitle & tab & pVer
  
  property pblnNotify : false
  
  --  Copyright © 2010, 2011 Robin Trew - Houthakker
  --  All rights reserved.
  -- 	
  -- 	Redistribution and use in source and binary forms, with or without modification, 
  -- 	are permitted provided that the following conditions are met:
  -- 	
  -- 		- Redistributions of source code must retain the above copyright notice, 
  -- 		  this list of conditions and the following disclaimer.
  -- 		- Redistributions in binary form must reproduce the above copyright notice, 
  -- 		  this list of conditions and the following disclaimer in the documentation 
  -- 		  and/or other materials provided with the distribution.
  -- 		
  -- 	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  -- 	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
  -- 	THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
  -- 	IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 
  -- 	ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  -- 	 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
  -- 	 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
  -- 	 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  -- 	 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
  --  RECENT CHANGE LOG
  
  -- ver 0.54	The first draft which aims to get data straight from Sqlite3, bypassing Sente XML
  -- ver 0.55	The pblnQuickTagsOnly option should now work correctly
  -- ver 0.56 Uses the PublicationTitle field in the folder name, if the Title field is empty
  -- ver 0.57 Purges "/" character from Titles / Publication Title to prevent inadvertent formation of subfolders
  -- ver 0.58	Avoids trailling commas after names of Authors when there is no year of publication
  -- ver 0.59 Adds a timeout interval for retrying locked data tables 
  --			Intended to facilitate exports of very large batches of records, which may otherwise trigger
  --			"database locked" errors. If you encounter these, try increasing the timeout length 
  --			(by editing the integer value of plngTimeout below)
  -- ver 0.60 Fixed an error tripped by records with HTML attachments rather than file attachments
  -- ver 0.61 Prevents duplication of simple WPMarker only records (created when references have no notes)
  -- ver 0.62 Adds pblnNotePosn switch: an option to follow page numbers with sortable position of note on page.
  -- ver 0.64 Changes the name of the css that it written/read (for compatibility with other scripts)
  -- 		(if you have customized a css file for this script, you will need to rename it or copy it to DevnNote.css)
  -- ver 0.65 Makes indexing of attachments optional - (edit pblnIndexAttachments below to false)
  -- ver 0.66 Adjusted notification to improve performance when Growl is not installed
  -- ver 0.67 Restored icon to Growl displays
  
  
  -- SCRIPT BEHAVIOUR
  property pblnIndexAttachments : true
  property pblnPageFirst : true -- Edit this to give records names which *start* with a sortable page number like "(@055)"  (otherwise at end of title)
  property pblnNotePosn : false -- Edit this to true to follow page number with sortable position of note on page
  property pblnAvoidDuplication : true -- If true, will not create duplicate records (on a second run) in the target group
  property pblnGetKeywordsAndTags : true
  property pblnQuickTagsOnly : false -- If true, will only export user-assigned keywords
  property plngTimeout : 250 -- 	Try opening locked SQLite tables for N milliseconds
  
  -- CSS FOR NOTE FORMATTTING
  property pstrDefaultCSS : "
   .header {color:#888888;}
   .quote {color:#333366; margin-left: 30px; margin-right: 30px; line-height: 140%;}
   .comment {color:#222222; margin-left: 30px; line-height: 140%;}
   .wptag {color:#888888;}
   .detail {color:#888888; margin-left: 30px; font-family: \"lucida grande\", \"sans-serif\"; font-size:8px;}
   struck {text-decoration:line-through}
   highlit {background-color:#FEFC97}
   underscored {text-decoration:underline}
    p {font-family: monospace; font-size:12px}
    i {font-family: monospace; font-style:italic;}
    b {font-family: monospace; font-weight:bold;}
    u {font-family: monospace}
   "
  property pstrActiveCSS : "" -- will be defined at run-time either by pstrDefaultCSS (above),
  --									or by the contents of any external pCSSfile (see below).
  
  --  An optional customized css file can be placed in the same folder as this script, 
  -- to retain customized formatting if a later version of this script is downloaded.
  -- The contents of this file (if its exists) will be used as an alternative to pstrDefaultCSS above,
  -- and should define the same set of styles. 
  -- If such a file is desired, it should have the name specified in the following property (pCSSFile):
  property pCSSFile : "DevnNote.css" -- changed the name to facilitate style sharing with other scripts (Skim exports etc).
  
  -- APPLICATION AND DATABASE LOCATIONS
  property pstrSenteAppPath : ""
  property pdbLib : missing value
  property pstrSQLite3 : "" -- path of the customized Sqlite3 executable inside the Sente app bundle
  property pstrDBPath : "" -- path of the Sqlite3 database within the Sente library bundle
  
  -- SQLITE3 QUERY ELEMENTS
  property pstrFldDelim : "~|~"
  property pstrEOSECTN : "\"<eosectn>\";"
  property pstrEOR : "<eor>"
  property pstrRefFields : "publicationYear, publicationTitle, articleTitle, AllAuthorNamesAsString, Citation, \"<eor>\""
  property pstrNoteFields : "Title, Pages, Quotation, Comment, LocationInAttachedFile, \"<eor>\""
  
  property pstrRefQuery : "SELECT " & pstrRefFields & " FROM Reference WHERE ReferenceUUID =\"" --& strUUID & "\";"
  property pstrNoteQuery : "SELECT " & pstrNoteFields & " FROM Note WHERE PrimaryReferenceUUID =\"" -- & strUUID & "\" AND IsDeleted=\"N\";
  
  -- GROWL URL
  property pGrowlURL : "http://growl.info/"
  
  on run
  	-- ARE DEVONTHINK AND SENTE RUNNING ?
  	if not AppsRunning() then return
  	
  	-- ARE ANY REFERENCES SELECTED IN SENTE ?
  	set {lstUUID, lstAttached} to SelectedRecords()
  	
  	set lngUUID to length of lstUUID
  	set lngAttached to length of lstAttached
  	if lngAttached ≠ lngUUID then
  		tell application id "sevs"
  			activate
  			display dialog (("Mismatch:
  " & lngUUID as string) & " UUIDS
  " & lngAttached as string) & " attachment lists ..."
  		end tell
  		return
  	end if
  	
  	if lngUUID < 1 then
  		tell application id "sevs"
  			activate
  			display alert "Select one or more references in Sente" as informational
  		end tell
  		return
  	end if
  	
  	-- GET A TARGET WINDOW AND GROUP IN DEVONTHINK
  	set {oGroup, oWin} to my GetGroupWin()
  	
  	-- 	PREPARE TO QUERY SQLITE3 DATABASE
  	set {pstrSQLite3, pstrDBPath} to GetProcessorAndDbPaths()
  	
  	-- 	IDENTIFY THE CSS TO BE USED FOR NOTE FORMATTING
  	set pstrActiveCSS to my GetCSS()
  	if (length of pstrActiveCSS) = 0 then set pstrActiveCSS to pstrDefaultCSS
  	
  	-- EXPORT NOTES
  	repeat with iRef from 1 to lngUUID
  		set strUUID to item iRef of lstUUID
  		SQLExportRef(oGroup, item iRef of lstUUID, item iRef of lstAttached)
  	end repeat
  	
  	-- OPTIONALLY NOTIFY COMPLETION BY GROWL OR DIALOG
  	--if pblnNotify then Growl(oGroup, lngUUID)
  	
  	-- DISPLAY THE TARGET GROUP (OR DATABASE OR INBOX) IN DT2
  	DT2ForeGround()
  end run
  
  on SQLExportRef(oGroup, strUUID, lstAttached)
  	
  	-- BUILD A SEQUENCE OF QUERIES TO RETRIEVE:
  	-- 1.	Simple fields of reference
  	-- 2		Separator
  	-- 3.	Keywords for this reference
  	-- 4.	Separator
  	-- 5.	Notes for this reference
  	
  	-- TIMEOUT LENGTH AND BASIC REFERENCE FIELDS
  	set strQuery to (".timeout " & plngTimeout as string) & "
  " & pstrRefQuery & strUUID & "\";
  SELECT " & pstrEOSECTN & "
  "
  	-- AND QUERIES FOR KEYWORDS (IF REQUIRED)
  	if pblnGetKeywordsAndTags then
  		set strQuery to strQuery & "SELECT KeywordValue, \"<eor>\" FROM KeyWord WHERE ReferenceUUID=\"" & strUUID & "\""
  		if pblnQuickTagsOnly then
  			set strQuery to strQuery & " AND Assigner like \"Sente User%\";
  SELECT " & pstrEOSECTN & "
  "
  		else
  			set strQuery to strQuery & ";
  SELECT " & pstrEOSECTN & "
  "
  		end if
  	end if
  	
  	-- AND QUERIES FOR NOTES
  	set strQuery to strQuery & pstrNoteQuery & strUUID & "\" AND IsDeleted=\"N\";"
  	
  	set strRunQuery to pstrSQLite3 & " -separator " & quoted form of pstrFldDelim & space & (quoted form of pstrDBPath) & space
  	set strSQL to "echo " & quoted form of strQuery & " | " & strRunQuery
  	
  	set text item delimiters to "<eosectn>" & return
  	
  	-- ** RUN THE SQL QUERY **
  	--set strReport to (do shell script strSQL)
  	set lstReport to text items of ((do shell script strSQL) & return)
  	
  	if length of lstReport ≠ 3 then
  		tell application id "sevs"
  			activate
  			display dialog "Unexpected SQL result"
  		end tell
  		return
  	end if
  	set {strFields, strKeyWords, strNotes} to lstReport
  	
  	-- GET THE RECORDS
  	set text item delimiters to "<eor>" & return
  	set lstFields to text items 1 thru -2 of strFields
  	if strKeyWords ≠ "" then
  		set lstKeyWords to items 1 thru -2 of (text items of strKeyWords)
  	else
  		set lstKeyWords to {}
  	end if
  	
  	if strNotes ≠ "" then
  		set lstNotes to (text items 1 thru -2 of (strNotes & "
  "))
  	else
  		set lstNotes to {}
  	end if
  	
  	-- AND GET THE FIELDS
  	set text item delimiters to pstrFldDelim
  	-- GET BASIC FIELDS
  	set lstFields to text items 1 thru -2 of (first item of lstFields)
  	
  	-- GET ANY KEYWORD FIELDS
  	repeat with i from 1 to length of lstKeyWords
  		set item i of lstKeyWords to first text item of (item i of lstKeyWords)
  	end repeat
  	
  	-- GET NOTES
  	repeat with i from 1 to length of lstNotes
  		set item i of lstNotes to text items 1 thru -2 of (item i of lstNotes)
  	end repeat
  	set text item delimiters to space
  	
  	-- MAKE / FIND THE DT FOLDER FOR THIS REFERENCE
  	set {strYear, strPublicnTitle, strTitle, strAuthors, strCitn} to lstFields
  	
  	set strSenteLibName to name of pdbLib
  	set {strRefNAme, strURL, strWPMarker} to BuildRefNameAndURL(strSenteLibName, strTitle, strPublicnTitle, strYear, strAuthors, strCitn)
  	tell application id "DNtp"
  		if (count of parents of oGroup) is 0 then
  			set oLocn to (create location strRefNAme in database of oGroup)
  		else
  			set oLocn to (create location (location of oGroup & "/" & name of oGroup & "/" & strRefNAme) in database of oGroup)
  		end if
  		
  		-- ADD TO ITS TAGS, IF REQUIRED
  		if pblnGetKeywordsAndTags then set tags of oLocn to (tags of oLocn) & lstKeyWords -- in case the folder already exists
  	end tell
  	
  	-- PUMP THE NOTES INTO IT
  	try
  		Notes2Devn(oLocn, lstNotes, strRefNAme, strURL, strWPMarker, lstAttached, lstKeyWords, strSenteLibName)
  	on error strMsg
  		tell application id "sevs"
  			activate
  			display alert strMsg & "
  		
  " & strRefNAme & return & strURL & return & strWPMarker
  		end tell
  	end try
  end SQLExportRef
  
  -- Place a set of notes in a suitably named DEVONthink folder in the currently selected group or database
  -- If no group or database is selected, the folder will be created in the global Inbox
  on Notes2Devn(oLocn, lstNotes, strRefNAme, strURL, strWPMarker, lstAttached, lstKeyWords, strSenteDbName)
  	--Title, Pages, Quotation, Comment, LocationInAttachedFile, AnnotationDetails
  	tell application id "DNtp"
  		if length of lstNotes > 0 then
  			if pblnPageFirst then -- Find the highest page number and count its digits
  				set lngMaxPage to 0
  				set my text item delimiters to space
  				repeat with oNote in lstNotes
  					set strPage to (item 2 of oNote)
  					if strPage contains space then set strPage to first item of text items of strPage
  					try
  						set lngPage to strPage as integer
  						if lngPage > lngMaxPage then set lngMaxPage to lngPage
  					end try
  				end repeat
  				set lngDigits to length of (lngMaxPage as string)
  			end if
  			
  			repeat with oNote in lstNotes
  				set {strTitle, strPages, strQuotn, strComment} to items 1 thru 4 of oNote
  				if strTitle contains "<" then
  					set strPlainTitle to do shell script "echo " & quoted form of strTitle & " | textutil -format html -convert txt -stdin -stdout"
  				else
  					set strPlainTitle to strTitle
  				end if
  				if strPages contains "<" then
  					set strPlainPages to do shell script "echo " & quoted form of strPages & " | textutil -format html -convert txt -stdin -stdout"
  				else
  					set strPlainPages to strPages
  				end if
  				
  				
  				if pblnNotePosn then
  					-- Try to get any Y position associated with the note
  					set strY to ""
  					set strNotePosn to (item 5 of oNote)
  					if strNotePosn ≠ "" then
  						set my text item delimiters to "Y\":"
  						set lstDetls to text items of strNotePosn
  						if length of lstDetls > 1 then
  							set strY to text item 2 of strNotePosn
  							set my text item delimiters to "."
  							set strY to my PadNum((first text item of strY) as integer, 4) & "y"
  							set my text item delimiters to space
  						end if
  					end if
  				end if
  				
  				if pblnPageFirst then
  					set my text item delimiters to space
  					set lngPage to 0
  					repeat with oPage in text items of strPlainPages
  						try
  							set lngPage to oPage as integer
  							if lngPage > 0 then exit repeat
  						end try
  					end repeat
  					
  					set strPadded to my PadNum(lngPage, lngDigits)
  					if pblnNotePosn then set strPadded to strPadded & "   " & strY
  					set strName to "(@" & strPadded & ")  " & strPlainTitle
  				else
  					set strName to strPlainTitle & "  (@" & strPages & ")"
  				end if
  				
  				
  				-- CHECK FOR EMBEDDED IMAGES IN THE QUOTATION
  				set blnHasImages to (strQuotn contains "<iimg>")
  				if blnHasImages then set strQuotn to my AddImgTags(strQuotn)
  				
  				set strText to "<p class=\"header\">Quotation:" & "<p class=\"quote\">" & strQuotn & "<p class=\"header\">" & ¬
  					"Comment:" & "<p class=\"comment\">" & strComment & ¬
  					"<p class=\"wptag\">" & "{" & strWPMarker & "@" & strPages & "}" & "<p>"
  				
  				set strHTML to "
  <!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">
  <html>
  <head>
    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
    <meta http-equiv=\"Content-Style-Type\" content=\"text/css\">
    <title></title>
    <style type=\"text/css\">
  " & pstrActiveCSS & "
    </style>
  </head>
  <body>" & strText & "</body>"
  				
  				-- CREATE THE FORMATTED RTF RECORD
  				if blnHasImages then -- Create an RTFD file and load it as a record
  					do shell script "echo " & quoted form of strHTML & " |  textutil -format html -convert rtfd -stdin -output ~/tmp.rtfd"
  					set oNewRec to import "~/tmp.rtfd" to oLocn
  					set URL of oNewRec to strURL
  					-- do shell script "rm ~/tmp.rtfd"
  				else -- Use DT's own HTML to RTF conversion
  					set oHTML to create record with {type:html, source:strHTML, URL:strURL} in oLocn
  					set oNewRec to convert record oHTML to rich
  					delete record oHTML
  				end if
  				set name of oNewRec to strName
  				
  				if pblnAvoidDuplication then
  					-- DISCARD NEW RECORD IF IT DUPLICATES ANOTHER IN THIS GROUP
  					set lstDuplics to duplicates of oNewRec
  					if lstDuplics ≠ {} then
  						set strLocn to location of oNewRec
  						repeat with oDuplic in lstDuplics
  							if location of oDuplic = strLocn then
  								delete record oNewRec
  								exit repeat
  							end if
  						end repeat
  					end if
  				end if
  			end repeat
  		else
  			-- in the absence of notes, create a DT2 record with a link back to the Sente record
  			-- and a pasteable WP Marker {Author Year}
  			set strName to "Link to (" & strWPMarker & ") in Sente"
  			set strText to "{" & strWPMarker & "}" & return
  			set oNewRec to create record with {type:rtf, rich text:strText, URL:strURL} in oLocn
  			if pblnAvoidDuplication then
  				-- DISCARD NEW RECORD IF IT DUPLICATES ANOTHER IN THIS GROUP
  				set lstDuplics to duplicates of oNewRec
  				if lstDuplics ≠ {} then
  					set strLocn to location of oNewRec
  					repeat with oDuplic in lstDuplics
  						if location of oDuplic = strLocn then
  							delete record oNewRec
  							exit repeat
  						end if
  					end repeat
  				end if
  			end if
  		end if
  		
  		if pblnIndexAttachments then
  			repeat with oAttached in lstAttached
  				set strURL to oAttached as string
  				if strURL begins with "file://localhost" then
  					set strPath to my URL2Path(strURL)
  					
  					set lstDuplic to (children of oLocn where path is strPath)
  					if length of lstDuplic < 1 then set oLinkRec to indicate strPath to oLocn
  				end if
  			end repeat
  		end if
  	end tell
  end Notes2Devn
  
  on AddImgTags(strQuotn)
  	-- REPLACE EACH <iimg> ... </iimg> SEQUENCE WITH AN <IMG SRC="data:image/tiff;base64,...> TAG
  	set text item delimiters to "iimg>"
  	set lstParts to text items of strQuotn
  	set lngParts to count of lstParts
  	set lngImages to lngParts div 2
  	if lngImages > 0 then
  		repeat with i from 1 to lngImages
  			set iImg to i * 2
  			-- DROP "<" at end of preceding group
  			set strPrecedg to (item (iImg - 1) of lstParts)
  			if length of strPrecedg > 1 then
  				set item (iImg - 1) of lstParts to text 1 thru -2 of strPrecedg
  			else
  				set item (iImg - 1) of lstParts to ""
  			end if
  			-- GET SEGMENT DATA (discarding tags at either end)
  			set strSegments to text 63 thru -13 of item iImg of lstParts
  			set item iImg of lstParts to TagImage(strSegments)
  		end repeat
  		set text item delimiters to linefeed
  		set strTagged to lstParts as string
  	else
  		set strTagged to strQuotn
  	end if
  	set text item delimiters to space
  	return strTagged
  end AddImgTags
  
  on TagImage(strData)
  	set text item delimiters to "</segment><segment>"
  	set lstParts to text items of strData
  	set text item delimiters to ""
  	set strTag to "<img src=\"data:image/tiff;base64," & (lstParts as string) & "\" />"
  	set text item delimiters to space
  	return strTag
  end TagImage
  
  on PadNum(lngNum, lngDigits)
  	set strNum to lngNum as string
  	set lngGap to (lngDigits - (length of strNum))
  	repeat while lngGap > 0
  		set strNum to "0" & strNum
  		set lngGap to lngGap - 1
  	end repeat
  	strNum
  end PadNum
  
  on BuildRefNameAndURL(strSenteDbName, strTitle, strPublicnTitle, strYear, strAuthors, strCitn)
  	
  	-- Purge any / character from the citation name
  	set strName to replaceString(strPublicnTitle, "/", " ")
  	set strTitle to replaceString(strTitle, "/", " ")
  	set strDbName to replaceString(strSenteDbName, " ", "+")
  	
  	-- Build contents of WP Marker (abbreviated citation for pasting in WP docs)
  	set strWPMarker to ""
  	
  	set text item delimiters to ", "
  	set lstParts to text items of strAuthors
  	set strAuthor to ""
  	if length of lstParts > 0 then set strAuthor to item 1 of lstParts
  	set strAuthor to trim(strAuthor)
  	set strYear to trim(strYear)
  	
  	
  	set strWPMarker to replaceString(strAuthor, space, "")
  	if length of strYear > 0 then
  		if not (strWPMarker contains strYear) then set strWPMarker to strWPMarker & " " & strYear
  	end if
  	
  	-- Build URL
  	set strURL to "sente://" & strDbName & "/"
  	if strWPMarker contains " " then
  		set strURL to strURL & replaceString(strWPMarker, " ", "+")
  	else
  		set strURL to strURL & strWPMarker
  	end if
  	if strTitle = "" then set strTitle to strName
  	
  	return {strWPMarker & " " & strTitle, strURL, strWPMarker}
  end BuildRefNameAndURL
  
  on AppendPart(strStem, strAddn, strDelim)
  	set strAddn to trim(strAddn)
  	if length of strAddn > 0 then
  		if strStem contains strAddn then
  			return strStem
  		else
  			if length of strStem > 0 then
  				set strStem to strStem & strDelim & strAddn
  			else
  				set strStem to strAddn
  			end if
  		end if
  	end if
  	strStem
  end AppendPart
  
  on trim(strText)
  	if length of strText > 0 then
  		set lstWhiteSpace to {" ", tab, ASCII character 10, return, ASCII character 0}
  		
  		repeat until first character of strText is not in lstWhiteSpace
  			set strText to text 2 thru -1 of strText
  		end repeat
  		
  		repeat until last character of strText is not in lstWhiteSpace
  			set strText to text 1 thru -2 of strText
  		end repeat
  		
  		return strText
  	else
  		return ""
  	end if
  end trim
  
  -- Replace a sub string
  on replaceString(theText, oldString, newString)
  	set AppleScript's text item delimiters to oldString
  	set tempList to every text item of theText
  	set AppleScript's text item delimiters to newString
  	set theText to the tempList as string
  	set AppleScript's text item delimiters to ""
  	return theText
  end replaceString
  
  on GetProcessorAndDbPaths()
  	tell application id "SntE"
  		set pstrSenteAppPath to POSIX path of (path to it)
  		set strLibPath to path of current library
  	end tell
  	
  	tell application id "sevs"
  		tell contents of property list file (strLibPath & "/Contents/info.plist")
  			set strBundle to value of property list item "CFBundleIdentifier"
  		end tell
  	end tell
  	
  	set text item delimiters to "."
  	set strSuffix to (last text item of strBundle)
  	set text item delimiters to space
  	
  	set pstrDBPath to strLibPath & "/Contents/" & "primaryLibrary." & strSuffix
  	set pstrSQLite3 to quoted form of (pstrSenteAppPath & "Contents/MacOS/sqlite3")
  	{pstrSQLite3, pstrDBPath}
  end GetProcessorAndDbPaths
  
  -- ARE DEVONTHINK AND SENTE RUNNING ?
  on AppsRunning()
  	tell application id "sevs"
  		if (count of (processes where creator type = "DNtp")) < 1 then
  			activate
  			display alert "First select a target folder in DEVONthink" as informational
  			return false
  		end if
  		if (count of (processes where creator type = "SntE")) < 1 then
  			activate
  			display alert "First select some records in Sente" as informational
  			return false
  		end if
  	end tell
  	true
  end AppsRunning
  
  on SelectedRecords()
  	tell application id "SntE"
  		set pdbLib to current library
  		if pdbLib is missing value then return {{}, {}}
  		
  		
  		--set strTags to retrieve selected references pdbLib as tags
  		set strXML to retrieve selected references pdbLib as sentexml
  		set strEndNote to retrieve selected references pdbLib as endnotexml
  		
  		-- YANK THE UUIDS OUT OF THE XML BY SIMPLE BRUTE FORCE
  		set my text item delimiters to "UUID\">"
  		set lstUUID to text items of strXML
  		set strXML to ""
  		set my text item delimiters to space
  		
  		set lngUUID to (length of lstUUID) - 1
  		if lngUUID < 1 then
  			tell application id "sevs"
  				activate
  				display alert "Select some references in Sente" as informational
  			end tell
  			return {}
  		end if
  		set lstUUID to items 2 thru end of lstUUID
  		repeat with i from 1 to lngUUID
  			set item i of lstUUID to {(text 1 thru 36 of (item i of lstUUID))}
  		end repeat
  		
  	end tell
  	-- SEGMENT THE ENDNOTE XML AND GRAB ANY ATTACHMENT LOCATIONS (OPAQUE IN THE SQLITE DATABASE)
  	set lstAttached to GetAttachLists(strEndNote)
  	return {lstUUID, lstAttached}
  end SelectedRecords
  
  
  on GetAttachLists(strEndNoteXML)
  	set text item delimiters to "<record>"
  	set lstRecs to text items of strEndNoteXML
  	if length of lstRecs > 1 then
  		set lstRecs to items 2 thru end of lstRecs
  	else
  		set text item delimiters to space
  		return {}
  	end if
  	
  	repeat with i from 1 to length of lstRecs
  		set item i of lstRecs to GrabURLS(item i of lstRecs)
  	end repeat
  	lstRecs
  end GetAttachLists
  
  on GrabURLS(strRec)
  	set strPrefix to "file://localhost"
  	set lst to {}
  	set text item delimiters to "<url>"
  	set lstParts to text items of strRec
  	set lngParts to length of lstParts
  	if lngParts > 1 then
  		set text item delimiters to strPrefix
  		repeat with i from 2 to lngParts
  			set lstFiles to text items of (item i of lstParts)
  			set lngSubParts to length of lstFiles
  			if lngSubParts > 1 then
  				set text item delimiters to "</style></url>"
  				repeat with j from 2 to lngSubParts
  					set lstURL to text items of (item j of lstFiles)
  					if length of lstURL > 1 then ¬
  						set end of lst to strPrefix & URL2Path(strPrefix & first item of lstURL)
  				end repeat
  			else
  				set text item delimiters to space
  				return {}
  			end if
  		end repeat
  	else
  		set text item delimiters to space
  		return {}
  	end if
  	lst
  end GrabURLS
  
  on URL2Path(strURL)
  	return do shell script "/usr/bin/python -c '" & ¬
  		"from sys import argv; " & ¬
  		"from urllib import unquote; " & ¬
  		"from urlparse import urlparse; " & ¬
  		"print unquote(urlparse(argv[1])[2])' " & quoted form of strURL
  end URL2Path
  
  on GetGroupWin()
  	tell application id "DNtp"
  		-- CURRENT GROUP, IF THERE IS ONE
  		set oGroup to missing value
  		with timeout of 1 second
  			try
  				set oGroup to current group
  			end try
  		end timeout
  		
  		-- ELSE CURRENT DATABASE, IF THERE IS ONE
  		try
  			oGroup
  		on error
  			set oGroup to (root of database id 1)
  			set oWin to open window for record oGroup
  			return {oGroup, oWin}
  		end try
  		
  		if oGroup is missing value then
  			set oGroup to (root of database id 1)
  			set oWin to open window for record oGroup
  			return {oGroup, oWin}
  		end if
  		
  		-- ENSURE THAT A WINDOW IS OPEN FOR THIS GROUP
  		set {oDb, strID} to {database, id} of oGroup
  		set lstWins to viewer windows where id of its root is strID and name of its root is name of oDb
  		if length of lstWins < 1 then
  			set oWin to open window for record oGroup
  		else
  			set oWin to first item of lstWins
  		end if
  		{oGroup, oWin}
  	end tell
  end GetGroupWin
  
  on GetCSS() -- Try to get the CSS file from the same folder as the script. If not there, return empty string
  	set strcssPath to my GetCSSPath(my pCSSFile)
  	set strCSS to ""
  	if strcssPath is not "" then
  		try
  			set strCSS to do shell script "cat " & quoted form of strcssPath
  		end try
  	end if
  	strCSS
  end GetCSS
  
  on GetCSSPath(strcssFile)
  	set strFolder to ScriptFolder() as string
  	set strcssPath to POSIX path of (strFolder & strcssFile)
  	tell application "Finder"
  		if not (exists (strcssPath as POSIX file)) then return ""
  	end tell
  	strcssPath
  end GetCSSPath
  
  on ScriptFolder()
  	set strPath to (path to me) as string
  	set strDelim to text item delimiters
  	set text item delimiters to ":"
  	set lstParts to text items of strPath
  	set lngLast to (length of lstParts) - 1
  	set strFolderPath to (items 1 thru lngLast of lstParts) as string
  	set text item delimiters to strDelim
  	strFolderPath as alias
  end ScriptFolder
  
  on Growl(oGroup, lngRefs)
  	tell application id "DNtp"
  		set {strFolder, strDb} to {name, name of database} of oGroup
  		set strTarget to "current folder:" & return & "[" & strFolder & "]" & return & "of DEVONthink database \"" & strDb & "\""
  	end tell
  	
  	set strReport to "Exported notes for " & pl("reference", lngRefs) & " to " & strTarget
  	set strAppName to name of application id "DNtp"
  	Notify(strAppName, "Notes sent to DEVONthink", strReport)
  end Growl
  
  on pl(str, lng)
  	if lng > 1 then
  		(lng as string) & space & str & "s"
  	else
  		(lng as string) & space & str
  	end if
  end pl
  
  ---- REPORT RESULTS TO USER ( BY DEFAULT THROUGH GROWL - IF INSTALLED )
  --on Notify(strAPP, strTitle, strReport)
  --	set strGrowlPath to ""
  --	try
  --		tell application "Finder" to tell (application file id "GRRR") to set strGrowlPath to POSIX path of (its container as alias) & name
  --	end try
  --	set blnInstalled to (strGrowlPath ≠ "")
  --	
  --	-- IF INSTALLED, THEN IS IT RUNNING ?
  --	if blnInstalled then
  --		tell application id "sevs"
  --			set blnGrowlRunning to length of ((application processes where name contains "Growl") as list) > 0
  --			
  --			-- IF NOT RUNNING THEN TRY TO WAKE IT UP ...
  --			if not blnGrowlRunning then
  --				do shell script "open -a " & quoted form of strGrowlPath
  --				do shell script "sleep .5"
  --				set blnGrowlRunning to exists (application process "GrowlHelperApp")
  --			end if
  --			
  --			if blnGrowlRunning then
  --				tell application "Growl"
  --					register as application "houthakker scripts" all notifications {strTitle} default notifications {strTitle} icon of application strAPP
  --					notify with name strTitle title strTitle application name "houthakker scripts" description strReport
  --				end tell
  --			else
  --				-- IF NO REPORT HAS BEEN MADE THROUGH GROWL, REPORT THRU DIALOG
  --				set strReport to "(Growl not running)" & return & return & strReport
  --				tell application id "sevs"
  --					activate
  --					display dialog strReport buttons {"OK"} default button 1 with title pTitle
  --				end tell
  --			end if
  --		end tell
  --	else
  --		-- IF GROWL IS NOT INSTALLED , REPORT THROUGH DIALOG
  --		set strReport to "(Growl not installed)" & return & return & strReport
  --		tell application id "sevs"
  --			activate
  --			tell (display dialog strReport buttons {pGrowlURL, "OK"} default button 2 with title pTitle)
  --				if button returned = pGrowlURL then tell me to do shell script "open " & quoted form of pGrowlURL
  --			end tell
  --		end tell
  --	end if
  --end Notify
  
  on DT2ForeGround()
  	tell application id "com.devon-technologies.thinkpro2"
  		hide progress indicator
  		activate
  	end tell
  	
  	tell application id "com.apple.finder"
  		activate front window of application id "com.devon-technologies.thinkpro2"
  	end tell
  end DT2ForeGround
  