on newPresentation(themeName)
	tell application "Keynote"
		activate
		-- FIXME: Make this selectable?
		set targetWidth to 1024 -- 1440 <-- higher resolution
		set targetHeight to 768 -- 1080 <-- higher resolution

		set props to {document theme:theme (themeName as string), width:targetWidth, height:targetHeight}

		set thisDocument to make new document with properties props
		return name of thisDocument
	end tell
end newPresentation

on savePresentation(docname, posixPath)
	tell application "Keynote"
		save document named docname in POSIX file posixPath
	end tell
end savePresentation

on createSlide(docname, masterSlideName)
	try
		tell application "Keynote"
			tell document named docname
				set thisSlide to make new slide with properties {base slide:master slide masterSlideName}
			end tell
	  return thisSlide
		end tell
	on error
		return 0
	end try
end createSlide

on finalize(docname)
	tell application "Keynote"
		tell document named docname to delete slide 1
	end tell
end finalize

on themeMasters(docname)
	--	  tell application "Keynote" to get the name of every master slide of thisDocument
	tell application "Keynote"
		set names to the name of every master slide of document named docname
		return names
	end tell
end themeMasters

on addImage(docname, filepath)
  (*
	FIXME: Use slide ID to adress slide instead of "current slide"
  *)
  tell application "Keynote"
	tell document named docname
		tell the current slide

			-- TO REPLACE A PLACEHOLDER OR EXISTING IMAGE:
			set thisPlaceholderImageItem to image 1
			-- change the value of the “file name” property of the image to be an HFS file reference to the replacement image file
		set macPath to POSIX file filepath as Unicode text
			set file name of thisPlaceholderImageItem to ¬
				alias macPath

		end tell
	end tell
  end tell
end addImage

on addTitle(docname, thisSlideTitle)
  (*
	FIXME: Use slide ID to adress slide instead of "current slide"
  *)
	tell application "Keynote"
		tell document named docname
			tell the current slide
				if title showing is true then
					set the object text of the default title item to thisSlideTitle
				end if
			end tell
		end tell
	end tell
end addTitle

on addBody(docname, thisSlideBody)
  (*
	FIXME: Use slide ID to adress slide instead of "current slide"
  *)
	tell application "Keynote"
		tell document named docname
			tell the current slide
				if body showing is true then
					set the object text of the default body item to thisSlideBody
				end if
			end tell
		end tell
	end tell
end addTitle

on newPresentation(themeName)
	tell application "Keynote"
		activate
		-- FIXME: Make this selectable?
		set targetWidth to 1024 -- 1440 <-- higher resolution
		set targetHeight to 768 -- 1080 <-- higher resolution

		set props to {document theme:theme (themeName as string), width:targetWidth, height:targetHeight}

		set thisDocument to make new document with properties props
		return name of thisDocument
	end tell
end newPresentation

on openPresentation(posixPath)
	tell application "Keynote"
		open posixPath
	end tell
end openPresentation

on savePresentation(docname, posixPath)
	tell application "Keynote"
		save document named docname in POSIX file posixPath
	end tell
end savePresentation

on createSlide(docname, masterSlideName)
	try
		tell application "Keynote"
			tell document named docname
				set thisSlide to make new slide with properties {base slide:master slide masterSlideName}
			end tell
	  return thisSlide
		end tell
	on error
		return 0
	end try
end createSlide

on finalize(docname)
	tell application "Keynote"
		tell document named docname to delete slide 1
	end tell
end finalize

on themeMasters(docname)
	--	  tell application "Keynote" to get the name of every master slide of thisDocument
	tell application "Keynote"
		set names to the name of every master slide of document named docname
		return names
	end tell
end themeMasters

on addImage(docname, filepath)
  (*
	FIXME: Use slide ID to adress slide instead of "current slide"
  *)
  tell application "Keynote"
	tell document named docname
		tell the current slide

			-- TO REPLACE A PLACEHOLDER OR EXISTING IMAGE:
			set thisPlaceholderImageItem to image 1
			-- change the value of the “file name” property of the image to be an HFS file reference to the replacement image file
		set macPath to POSIX file filepath as Unicode text
			set file name of thisPlaceholderImageItem to ¬
				alias macPath

		end tell
	end tell
  end tell
end addImage

on addTitle(docname, thisSlideTitle)
  (*
	FIXME: Use slide ID to adress slide instead of "current slide"
  *)
	tell application "Keynote"
		tell document named docname
			tell the current slide
				if title showing is true then
					set the object text of the default title item to thisSlideTitle
				end if
			end tell
		end tell
	end tell
end addTitle

on addBody(docname, thisSlideBody)
  (*
	FIXME: Use slide ID to adress slide instead of "current slide"
  *)
	tell application "Keynote"
		tell document named docname
			tell the current slide
				if body showing is true then
					set the object text of the default body item to thisSlideBody
				end if
			end tell
		end tell
	end tell
end addTitle

Add openPresentation

Add openPresentation


-- BBEdit_upgrade_SQL_Query_to_newer_format({})
-- Dan Shockley, NYHTC
-- BBEdit - upgrade SQL Query to newer format

(*
HISTORY:
	1.1 - 2017-12-11 ( dshockley ): disable the usually no-longer-needed SQL_EscapeString, but WARN and comment, since it might sitll be needed when using with something OTHER THAN SQL_Where criteria.
	1.0 - 2017-09-15 ( dshockley ): first created.
*)

on run
	BBEdit_upgrade_SQL_Query_to_newer_format({})
end run

--------------------
-- START OF CODE
--------------------

on BBEdit_upgrade_SQL_Query_to_newer_format({})

	set regexSearch_SQL_Table to "Quote *\\( *TableNameOfField *\\( *([^\\)]+) *\\) *\\)"
	set regexReplace_SQL_Table to "SQL_Table ( \\1 )"

	set regexSearch_SQL_Field to "Quote *\\( ?FieldNameShort *\\( *([^\\)]+) *\\) *\\)"
	set regexReplace_SQL_Field to "SQL_Field ( \\1 )"

	set regexSearch_WhereEqualsClause to "^([\\t ]*)& *SQL_Field *\\( *([^\\)]+) *\\)
[\\t ]*& \" *= *\"
[\\t ]*& ([^\\r]+)\\r"

	set regexReplace_WhereEqualsClause to "\\1\\& SQL_Where ( \\2 ; \"=\" ; \\3 )\\r"

	set regexSearch_EscapeStringWARN to "SQL_EscapeString *\\( *([^\\)]+) *\\)"

	set regexReplace_EscapeStringWARN to "\\1 /* WARNING!! Had SQL_EscapeString probably NO LONGER NEEDED, so DISABLED! */"

	tell application "BBEdit"
		activate

		tell window 1

			replace regexSearch_SQL_Table using regexReplace_SQL_Table options {search mode:grep, starting at top:true}

			replace regexSearch_SQL_Field using regexReplace_SQL_Field options {search mode:grep, starting at top:true}

			replace regexSearch_WhereEqualsClause using regexReplace_WhereEqualsClause options {search mode:grep, starting at top:true}
			replace regexSearch_EscapeStringWARN using regexReplace_EscapeStringWARN options {search mode:grep, starting at top:true}

		end tell

	end tell
end BBEdit_upgrade_SQL_Query_to_newer_format

--------------------
-- END OF CODE
--------------------

-- BBEdit_upgrade_SQL_Query_to_newer_format({})
-- Dan Shockley, NYHTC
-- BBEdit - upgrade SQL Query to newer format

(*
HISTORY:
	1.2 - 2018-05-22 ( dshockley ): modified to also convert the query to use List to separate the components of the query.
	1.1 - 2017-12-11 ( dshockley ): disable the usually no-longer-needed SQL_EscapeString, but WARN and comment, since it might sitll be needed when using with something OTHER THAN SQL_Where criteria.
	1.0 - 2017-09-15 ( dshockley ): first created.
*)

on run
	BBEdit_upgrade_SQL_Query_to_newer_format({})
end run

--------------------
-- START OF CODE
--------------------

on BBEdit_upgrade_SQL_Query_to_newer_format({})

	set regexSearch_SQL_Table to "Quote *\\( *TableNameOfField *\\( *([^\\)]+) *\\) *\\)"
	set regexReplace_SQL_Table to "SQL_Table ( \\1 )"

	set regexSearch_SQL_Field to "Quote *\\( ?FieldNameShort *\\( *([^\\)]+) *\\) *\\)"
	set regexReplace_SQL_Field to "SQL_Field ( \\1 )"

	set regexSearch_WhereEqualsClause to "^([\\t ]*)& *SQL_Field *\\( *([^\\)]+) *\\)
[\\t ]*& \" *= *\"
[\\t ]*& ([^\\r]+)\\r"

	set regexReplace_WhereEqualsClause to "\\1\\& SQL_Where ( \\2 ; \"=\" ; \\3 )\\r"

	set regexSearch_EscapeStringWARN to "SQL_EscapeString *\\( *([^\\)]+) *\\)"

	set regexReplace_EscapeStringWARN to "\\1 /* WARNING!! Had SQL_EscapeString probably NO LONGER NEEDED, so DISABLED! */"

	tell application "BBEdit"
		activate

		tell window 1

			replace regexSearch_SQL_Table using regexReplace_SQL_Table options {search mode:grep, starting at top:true}

			replace regexSearch_SQL_Field using regexReplace_SQL_Field options {search mode:grep, starting at top:true}

			replace regexSearch_WhereEqualsClause using regexReplace_WhereEqualsClause options {search mode:grep, starting at top:true}
			replace regexSearch_EscapeStringWARN using regexReplace_EscapeStringWARN options {search mode:grep, starting at top:true}

			try
				(* convert to using List ( ) for whitespace formatting of query: *)
				set stringStartQuery to "; sqlQuery = "
				set stringEndQuery to "^([\\t]+); sqlResult = "
				set posQueryStart to characterOffset of found object of (find stringStartQuery)
				set posQueryEnd to (characterOffset of found object of (find stringEndQuery options {search mode:grep})) - 1
				select (characters posQueryStart through posQueryEnd)

				replace "\"SELECT" using "List ( \\r\\t\\t  \"SELECT" searching in selection options {search mode:grep}
				replace "^([\\t]+)& " using "\\t\\t; " searching in selection options {search mode:grep}

				set character posQueryEnd to return & tab & tab & ")" & (contents of character posQueryEnd)

			end try

		end tell

	end tell

end BBEdit_upgrade_SQL_Query_to_newer_format

--------------------
-- END OF CODE
--------------------

use List to format query

use List to format query


using terms from application "iChat"
  on message received message from theBuddy for textChat
    set whoDidIt to full name of theBuddy
    set buddyIcon to image of theBuddy
    set window_name to "Not iChat"

    tell application "System Events"
      set frontApp to name of first application process whose frontmost is true
    end tell

    if frontApp is equal to "iChat"
      tell application frontApp
        if the (count of documents) is not 0 then
          set window_name to name of front window
        end if
      end tell
    end if

    if window_name is not equal to "Chat with " & whoDidIt then
      tell application "GrowlHelperApp" -- ** the daemon that is behind the scenes
        -- Make a list of all the notification types that this script will ever send:
        set the allNotificationsList to {"IM Received"}

        -- Make a list of the notifications that will be enabled by default.
        set the enabledNotificationsList to {"IM Received"}

        -- Register our script with growl.
        register as application "iChat Growl AppleScript" all notifications allNotificationsList default notifications enabledNotificationsList icon of application "iChat"

        if buddyIcon is equal to missing value then
          notify with name "IM Received" title whoDidIt description message application name "iChat Growl AppleScript" sticky no
        else
          notify with name "IM Received" title whoDidIt description message application name "iChat Growl AppleScript" sticky no image buddyIcon
        end if
      end tell
    end if
  end message received
end using terms from

using terms from application "iChat"
  on message received message from theBuddy for textChat
    set whoDidIt to full name of theBuddy
    set buddyIcon to image of theBuddy

    tell application "System Events"
      set frontApp to name of first application process whose frontmost is true
    end tell

    if frontApp is not equal to "iChat" then
      tell application "GrowlHelperApp" -- ** the daemon that is behind the scenes
        -- Make a list of all the notification types that this script will ever send:
        set the allNotificationsList to {"IM Received"}

        -- Make a list of the notifications that will be enabled by default.
        set the enabledNotificationsList to {"IM Received"}

        -- Register our script with growl.
        register as application "iChat Growl AppleScript" all notifications allNotificationsList default notifications enabledNotificationsList icon of application "iChat"

        if buddyIcon is equal to missing value then
          notify with name "IM Received" title whoDidIt description message application name "iChat Growl AppleScript" sticky no identifier whoDidIt
        else
          notify with name "IM Received" title whoDidIt description message application name "iChat Growl AppleScript" sticky no identifier whoDidIt image buddyIcon
        end if
      end tell
    end if
  end message received
end using terms from

Fix some bugs in iChat growl

Fix some bugs in iChat growl


on run {input}
  try
    do shell script "$HOME/Dropbox\\ \\(Personal\\)/projects/plover-tools/plover-dictionary-lookup/dictlook -x " & "\"" & input & "\""
    display dialog result buttons {"OK"} default button 1
  on error
    display dialog "No such luck." buttons {"OK"} default button 1
    beep
  end try
end run

on run {input}
  try
    do shell script "$HOME/Dropbox\\ \\(Personal\\)/projects/plover-tools/plover-dictionary-lookup/dictlook -x " & "\"" & input & "\""
    display dialog result default answer "" buttons {"OK"} default button 1
  on error
    display dialog "No such luck." buttons {"OK"} default button 1
    beep
  end try
end run

Add practice text area to lookup dialog

Add practice text area to lookup dialog


property pTitle : "OmniFocus: Quick Stats"
property pVersion : "2.07.brett"

property pstrDBPath : "$HOME/Library/Containers/com.omnigroup.OmniFocus2/Data/Library/Caches/com.omnigroup.OmniFocus/OmniFocusDatabase2"
property pstrMinOSX : "10.9"

property pTimeOut : 30

-- Original version: https://github.com/RobTrew/tree-tools/blob/master/OmniFocus%20scripts/Statistics/QuickStats.applescript

-- Copyright  2012, 2013, 2014 Robin Trew
--
-- Permission is hereby granted, free of charge,
-- to any person obtaining a copy of this software
-- and associated documentation files (the "Software"),
-- to deal in the Software without restriction,
-- including without limitation the rights to use, copy,
-- modify, merge, publish, distribute, sublicense,
-- and/or sell copies of the Software, and to permit persons
-- to whom the Software is furnished to do so,
-- subject to the following conditions:
--
-- *******
-- The above copyright notice and this permission notice
-- shall be included in ALL copies
-- or substantial portions of the Software.
-- *******
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
-- OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-- Ver 0.8 adds clipboard option to dialogue
-- Ver 0.9 gives an error message if the cache schema has changed, leading to an SQL error in the script
-- Ver 1.0 slight simplification of the code
-- Ver 1.1 added count of Pending projects
-- Ver 1.2 added a count of available actions
-- Ver 1.3 added a break-down of unavailable actions
-- Ver 1.4 added count of Current projects to complement Pending projects
-- ver 1.5 replaced Applescript time function with SQL time expression
-- Ver 1.7 Reorganizes menu, and attempts to enable access for .macappstore installations of OF
--Ver 1.8 Adjusts handling of variant bundle identifiers generally
-- Ver 2.00 Redraft of task breakdown, with progressive narrowing of criteria ...

property pToClipboard : "Copy list to clipboard"

if not FileExists(pstrDBPath) then set pstrDBPath to GetCachePath()

tell application "Finder"
	if (version < pstrMinOSX) then
		display dialog "This script requires OSX " & pstrMinOSX & " or higher" buttons {"OK"} default button 1 with title pTitle & "Ver. " & pVersion
		return
	end if

	set screen_resolution to bounds of window of desktop
	set height to item 4 of screen_resolution
	if height < 1024 then
		set brief to true
	else
		set brief to false
	end if
end tell

if pstrDBPath  "" then
	set inbox_cmd to "
	select 'INBOX GROUPS & ACTIONS', count(*) from task where (inInbox=1);
	select '    Inbox action groups', count(*) from task where (inInbox=1) and (childrenCount>0);
	select '    Inbox actions', count(*) from task where (inInbox=1) and (childrenCount=0);
	select null;
	"
	set folders_cmd to "
	select 'FOLDERS'	, count(*) from folder;
	select '    Active folders', count(*) from folder where effectiveActive=1;
	select '    Dropped folders', count(*) from folder where effectiveActive=0;
	select null;
	"
	set projects_cmd to "
	select 'PROJECTS', count(*) from projectInfo where containsSingletonActions=0;
	select '    Active projects', count(*) from projectInfo where (containsSingletonActions=0) and (status='active');
	select '            Current projects', count(*) from projectInfo p join task t on t.projectinfo=p.pk where (p.containsSingletonActions=0) and (p.folderEffectiveActive=1) and (p.status='active') and (t.dateToStart is null or t.dateToStart < (strftime('%s','now') - strftime('%s','2001-01-01')));
	select '            Pending projects', count(*) from projectInfo p join task t on t.projectinfo=p.pk where (p.containsSingletonActions=0) and (p.folderEffectiveActive=1) and (p.status='active') and (t.dateToStart > (strftime('%s','now') - strftime('%s','2001-01-01')));
	select '    On-hold projects', count(*) from projectInfo where (containsSingletonActions=0) and (status='inactive');
	select '    Completed projects', count(*) from projectInfo where (containsSingletonActions=0) and (status='done');
	select '    Dropped projects', count(*) from projectInfo where (containsSingletonActions=0) and (( status='dropped') or (folderEffectiveActive=0));
	select null;
	"
	set lists_cmd to "
	select 'SINGLE ACTION LISTS', count(*) from projectInfo where containsSingletonActions=1;
	select '    Active single action lists', count(*) from projectInfo where (containsSingletonActions=1) and (status='active');
	select '    On-hold single action lists', count(*) from projectInfo where (containsSingletonActions=1) and (status='inactive');
	select '    Completed single action lists', count(*) from projectInfo where (containsSingletonActions=1) and (status='done');
	select '    Dropped single action lists', count(*) from projectInfo where (containsSingletonActions=1) and (( status='dropped') or (folderEffectiveActive=0));
	select null;
	"
	set contexts_cmd to "
	select 'CONTEXTS', count(*) from context;
	select '    Active contexts', count(*) from context where (effectiveActive=1) and (allowsNextAction=1);
	select '    On-hold contexts', count(*) from context where (effectiveActive=1) and allowsNextAction=0;
	select '    Dropped contexts', count(*) from context where effectiveActive=0;
	select null;
	"
	set groups_cmd to "
	select 'ACTION GROUPS', count(*) from task where (projectinfo is null) and (childrenCount>0);
	select '    Remaining action groups', count(*) from task where (projectinfo is null) and (dateCompleted is null) and (childrenCount>0);
	select '    Completed action groups', count(dateCompleted) from task where (projectinfo is null) and (childrenCount>0);
	select null;
	"
	set tasks_cmd to "
	select 'ALL TASKS', count(*) from task;
	select null;
	"
	set actions_cmd to "
	select 'ACTIONS', count(*) from task where (projectinfo is null) and (childrenCount=0);
	select '    Completed actions', count(dateCompleted) from task where (projectinfo is null) and (childrenCount=0);
	select '    Dropped project actions', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp where (projectinfo is null) and (childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is not null and (tp.status='dropped' or tp.folderEffectiveActive=0));
	select '    Dropped context actions', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and c.effectiveActive= 0;
	select '    Remaining actions', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.context is null or c.effectiveActive= 1);
	select '        Actions in Projects on hold', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.context is null or c.effectiveActive= 1)
				and (tp.containingProjectInfo is not null and tp.status='inactive');
	select '        Actions in Contexts on hold', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.context is null or c.effectiveActive= 1)
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and (tp.context is not null and c.allowsNextAction=0);
	select '        Blocked actions', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.context is null or c.effectiveActive= 1)
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and (tp.context is null or c.allowsNextAction=1)
				and tp.blocked=1;
	select '        	Blocked by future start date', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.context is null or c.effectiveActive= 1)
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and (tp.context is null or c.allowsNextAction=1)
				and tp.blocked=1
				and tp.blockedByFutureStartDate=1;
	select '        	Sequentially blocked', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.context is null or c.effectiveActive= 1)
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and (tp.context is null or c.allowsNextAction=1)
				and tp.blocked=1
				and tp.blockedByFutureStartDate=0;
	select '        Available actions', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.context is null or c.effectiveActive= 1)
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and (tp.context is null or c.allowsNextAction=1)
				and tp.blocked=0;
	select null;
	"
	set summary_cmd to "
	select 'SUMMARY';
	select '    Inbox available actions', count(*) from task where (inInbox=1) and (dateCompleted is null);
	select '    Due in next week', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (((projectinfo is null) and (tp.childrenCount=0))  or containsSingletonActions=0) and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and tp.blockedByFutureStartDate=0
				and effectiveDateDue <= strftime('%s','now','+7 days') - strftime('%s','2001-01-01');
	select '    Flagged projects and actions', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (((projectinfo is null) and (tp.childrenCount=0))  or containsSingletonActions=0) and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and tp.blockedByFutureStartDate=0
				and tp.effectiveFlagged;
	select '    Due or Flagged', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (((projectinfo is null) and (tp.childrenCount=0))  or containsSingletonActions=0) and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and tp.blockedByFutureStartDate=0
				and (tp.effectiveFlagged or (effectiveDateDue <= strftime('%s','now','+7 days') - strftime('%s','2001-01-01')));
	select null;
	"
	if brief then
		set commands to projects_cmd & lists_cmd & contexts_cmd & groups_cmd & actions_cmd & summary_cmd
	else
		set commands to inbox_cmd & folders_cmd & projects_cmd & lists_cmd & contexts_cmd & groups_cmd & actions_cmd & tasks_cmd & summary_cmd
	end if
	set strCmd to "sqlite3 -separator ': ' \"" & pstrDBPath & "\" " & quoted form of (commands)

	-- 		try
	set strList to do shell script strCmd
	-- 		on error
	-- 			display dialog "The SQL schema for the OmniFocus cache may have changed in a recent update of OF." & return & return &
	-- 				"Look on the OmniFocus user forums for an updated version of this script." buttons {"OK"} with title pTitle & "Ver. " & pVersion
	-- 			return
	-- 		end try
	tell application id "sevs"
		activate
		if button returned of (display dialog strList buttons {pToClipboard, "OK"} default button "OK" giving up after pTimeOut with title pTitle & " Ver. " & pVersion)
			is pToClipboard then tell application id "com.apple.finder" to set the clipboard to strList
	end tell
else
	tell application id "sevs"
		activate
		display dialog "OmniFocus cache not found ..." buttons {"OK"} default button 1 with title pTitle & " Ver. " & pVersion
	end tell
end if

on FileExists(strPath)
	(do shell script "test -e " & strPath & " ; echo $?") = "0"
end FileExists

on GetCachePath()
	try
		tell application "Finder" to tell (application file id "OFOC") to "$HOME/Library/Containers/com.omnigroup.OmniFocus2/Data/Library/Caches/" & its id & "/OmniFocusDatabase2"
	on error
		error "OmniFocus not installed ..."
	end try
end GetCachePath

property pTitle : "OmniFocus: Quick Stats"
property pVersion : "2.07.brett"

property pstrDBPath : "$HOME/Library/Containers/com.omnigroup.OmniFocus2/Data/Library/Caches/com.omnigroup.OmniFocus/OmniFocusDatabase2"
property pstrMinOSX : "10.9"

property pTimeOut : 30

-- Original version: https://github.com/RobTrew/tree-tools/blob/master/OmniFocus%20scripts/Statistics/QuickStats.applescript

-- Copyright  2012, 2013, 2014 Robin Trew
--
-- Permission is hereby granted, free of charge,
-- to any person obtaining a copy of this software
-- and associated documentation files (the "Software"),
-- to deal in the Software without restriction,
-- including without limitation the rights to use, copy,
-- modify, merge, publish, distribute, sublicense,
-- and/or sell copies of the Software, and to permit persons
-- to whom the Software is furnished to do so,
-- subject to the following conditions:
--
-- *******
-- The above copyright notice and this permission notice
-- shall be included in ALL copies
-- or substantial portions of the Software.
-- *******
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
-- OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-- Ver 0.8 adds clipboard option to dialogue
-- Ver 0.9 gives an error message if the cache schema has changed, leading to an SQL error in the script
-- Ver 1.0 slight simplification of the code
-- Ver 1.1 added count of Pending projects
-- Ver 1.2 added a count of available actions
-- Ver 1.3 added a break-down of unavailable actions
-- Ver 1.4 added count of Current projects to complement Pending projects
-- ver 1.5 replaced Applescript time function with SQL time expression
-- Ver 1.7 Reorganizes menu, and attempts to enable access for .macappstore installations of OF
--Ver 1.8 Adjusts handling of variant bundle identifiers generally
-- Ver 2.00 Redraft of task breakdown, with progressive narrowing of criteria ...

property pToClipboard : "Copy list to clipboard"

if not FileExists(pstrDBPath) then set pstrDBPath to GetCachePath()

tell application "Finder"
	if (version < pstrMinOSX) then
		display dialog "This script requires OSX " & pstrMinOSX & " or higher" buttons {"OK"} default button 1 with title pTitle & "Ver. " & pVersion
		return
	end if

	set screen_resolution to bounds of window of desktop
	set height to item 4 of screen_resolution
	if height < 1024 then
		set brief to true
	else
		set brief to false
	end if
end tell

if pstrDBPath  "" then
	set inbox_cmd to "
	select 'INBOX GROUPS & ACTIONS', count(*) from task where (inInbox=1);
	select '    Inbox action groups', count(*) from task where (inInbox=1) and (childrenCount>0);
	select '    Inbox actions', count(*) from task where (inInbox=1) and (childrenCount=0);
	select null;
	"
	set folders_cmd to "
	select 'FOLDERS'	, count(*) from folder;
	select '    Active folders', count(*) from folder where effectiveActive=1;
	select '    Dropped folders', count(*) from folder where effectiveActive=0;
	select null;
	"
	set projects_cmd to "
	select 'PROJECTS', count(*) from projectInfo where containsSingletonActions=0;
	select '    Active projects', count(*) from projectInfo where (containsSingletonActions=0) and (status='active');
	select '            Current projects', count(*) from projectInfo p join task t on t.projectinfo=p.pk where (p.containsSingletonActions=0) and (p.folderEffectiveActive=1) and (p.status='active') and (t.dateToStart is null or t.dateToStart < (strftime('%s','now') - strftime('%s','2001-01-01')));
	select '            Pending projects', count(*) from projectInfo p join task t on t.projectinfo=p.pk where (p.containsSingletonActions=0) and (p.folderEffectiveActive=1) and (p.status='active') and (t.dateToStart > (strftime('%s','now') - strftime('%s','2001-01-01')));
	select '    On-hold projects', count(*) from projectInfo where (containsSingletonActions=0) and (status='inactive');
	select '    Completed projects', count(*) from projectInfo where (containsSingletonActions=0) and (status='done');
	select '    Dropped projects', count(*) from projectInfo where (containsSingletonActions=0) and (( status='dropped') or (folderEffectiveActive=0));
	select null;
	"
	set lists_cmd to "
	select 'SINGLE ACTION LISTS', count(*) from projectInfo where containsSingletonActions=1;
	select '    Active single action lists', count(*) from projectInfo where (containsSingletonActions=1) and (status='active');
	select '    On-hold single action lists', count(*) from projectInfo where (containsSingletonActions=1) and (status='inactive');
	select '    Completed single action lists', count(*) from projectInfo where (containsSingletonActions=1) and (status='done');
	select '    Dropped single action lists', count(*) from projectInfo where (containsSingletonActions=1) and (( status='dropped') or (folderEffectiveActive=0));
	select null;
	"
	set contexts_cmd to "
	select 'CONTEXTS', count(*) from context;
	select '    Active contexts', count(*) from context where (effectiveActive=1) and (allowsNextAction=1);
	select '    On-hold contexts', count(*) from context where (effectiveActive=1) and allowsNextAction=0;
	select '    Dropped contexts', count(*) from context where effectiveActive=0;
	select null;
	"
	set groups_cmd to "
	select 'ACTION GROUPS', count(*) from task where (projectinfo is null) and (childrenCount>0);
	select '    Remaining action groups', count(*) from task where (projectinfo is null) and (dateCompleted is null) and (childrenCount>0);
	select '    Completed action groups', count(dateCompleted) from task where (projectinfo is null) and (childrenCount>0);
	select null;
	"
	set tasks_cmd to "
	select 'ALL TASKS', count(*) from task;
	select null;
	"
	set actions_cmd to "
	select 'ACTIONS', count(*) from task where (projectinfo is null) and (childrenCount=0);
	select '    Completed actions', count(dateCompleted) from task where (projectinfo is null) and (childrenCount=0);
	select '    Dropped project actions', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp where (projectinfo is null) and (childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is not null and (tp.status='dropped' or tp.folderEffectiveActive=0));
	select '    Dropped context actions', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and c.effectiveActive= 0;
	select '    Remaining actions', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.context is null or c.effectiveActive= 1);
	select '        Actions in Projects on hold', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.context is null or c.effectiveActive= 1)
				and (tp.containingProjectInfo is not null and tp.status='inactive');
	select '        Actions in Contexts on hold', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.context is null or c.effectiveActive= 1)
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and (tp.context is not null and c.allowsNextAction=0);
	select '        Blocked actions', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.context is null or c.effectiveActive= 1)
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and (tp.context is null or c.allowsNextAction=1)
				and tp.blocked=1;
	select '        	Blocked by future start date', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.context is null or c.effectiveActive= 1)
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and (tp.context is null or c.allowsNextAction=1)
				and tp.blocked=1
				and tp.blockedByFutureStartDate=1;
	select '        	Sequentially blocked', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.context is null or c.effectiveActive= 1)
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and (tp.context is null or c.allowsNextAction=1)
				and tp.blocked=1
				and tp.blockedByFutureStartDate=0;
	select '        Available actions', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (projectinfo is null) and (tp.childrenCount=0)  and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.context is null or c.effectiveActive= 1)
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and (tp.context is null or c.allowsNextAction=1)
				and tp.blocked=0;
	select null;
	"
	set summary_cmd to "
	select 'SUMMARY';
	select '    Inbox available actions', count(*) from task where (inInbox=1) and (dateCompleted is null);
	select '    Due in next week', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (((projectinfo is null) and (tp.childrenCount=0))  or containsSingletonActions=0) and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and tp.blockedByFutureStartDate=0
				and effectiveDateDue <= strftime('%s','now','+7 days') - strftime('%s','2001-01-01');
	select '    Flagged projects and actions', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (((projectinfo is null) and (tp.childrenCount=0))  or containsSingletonActions=0) and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and tp.blockedByFutureStartDate=0
				and tp.effectiveFlagged;
	select '    Due or Flagged', count(*) from (task t left join projectinfo p on t.containingProjectinfo=p.pk) tp left join context c on tp.context=c.persistentIdentifier where (((projectinfo is null) and (tp.childrenCount=0))  or containsSingletonActions=0) and (dateCompleted is null)
				and (tp.containingProjectinfo is null or (tp.status !='dropped' and tp.folderEffectiveActive=1))
				and (tp.containingProjectInfo is null or tp.status!='inactive')
				and tp.blockedByFutureStartDate=0
				and (tp.effectiveFlagged or (effectiveDateDue <= strftime('%s','now','+7 days') - strftime('%s','2001-01-01')));
	select null;
	"
	if brief then
		set commands to summary_cmd & actions_cmd & projects_cmd & contexts_cmd
	else
		set commands to summary_cmd & actions_cmd & inbox_cmd & folders_cmd & projects_cmd & lists_cmd & contexts_cmd & groups_cmd & tasks_cmd
	end if
	set strCmd to "sqlite3 -separator ': ' \"" & pstrDBPath & "\" " & quoted form of (commands)

	-- 		try
	set strList to do shell script strCmd
	-- 		on error
	-- 			display dialog "The SQL schema for the OmniFocus cache may have changed in a recent update of OF." & return & return &
	-- 				"Look on the OmniFocus user forums for an updated version of this script." buttons {"OK"} with title pTitle & "Ver. " & pVersion
	-- 			return
	-- 		end try
	tell application id "sevs"
		activate
		if button returned of (display dialog strList buttons {pToClipboard, "OK"} default button "OK" giving up after pTimeOut with title pTitle & " Ver. " & pVersion)
			is pToClipboard then tell application id "com.apple.finder" to set the clipboard to strList
	end tell
else
	tell application id "sevs"
		activate
		display dialog "OmniFocus cache not found ..." buttons {"OK"} default button 1 with title pTitle & " Ver. " & pVersion
	end tell
end if

on FileExists(strPath)
	(do shell script "test -e " & strPath & " ; echo $?") = "0"
end FileExists

on GetCachePath()
	try
		tell application "Finder" to tell (application file id "OFOC") to "$HOME/Library/Containers/com.omnigroup.OmniFocus2/Data/Library/Caches/" & its id & "/OmniFocusDatabase2"
	on error
		error "OmniFocus not installed ..."
	end try
end GetCachePath

bring summary and actions to top, trim list in brief mode


-- fmGUI_ManageDb_Open(prefs)
-- Daniel A. Shockley, NYHTC
-- Open Manage Database

(*
HISTORY:
	1.4 - 2020-05-20 ( dshockley ): added multiple missing sub-handlers. Removed referfence to old sub-handler.
	1.3 - 2018-04-30 ( eshagdar ): get window name via handler.
	1.2 - added xDBC connection error trapping
	1.1 -
	1.0 - created

TODO:
	- 2015-06-03 ( eshagdar ): probably going to need to open manageDB via openManageDB script if the menu item fails

REQUIRES:
	fmGUI_AppFrontMost
	fmGUI_ManageDb_DismissXDBCDialog
	fmGUI_ManageDb_GoToTab_Relationships
	fmGUI_Menu_OpenDB
	fmGUI_NameOfFrontmostWindow
*)

on run
	fmGUI_ManageDb_Open({})
end run

--------------------
-- START OF CODE
--------------------

on fmGUI_ManageDb_Open(prefs)
	-- version 1.4

	try
		fmGUI_AppFrontMost()

		-- try to open Manage DB
		set windowName to fmGUI_NameOfFrontmostWindow()
		if windowName starts with "Manage Database for" then
			return true
		else
			fmGUI_Menu_OpenDB({})

			-- dismiss any initial xDBC connection errors
			fmGUI_ManageDb_DismissXDBCDialog({})

			-- go to the TOs tab and AGAIN dismiss any xDBC connections that failed to connect
			fmGUI_ManageDb_GoToTab_Relationships({})
			delay 1
			fmGUI_ManageDb_DismissXDBCDialog({})

			--zoom out to show all TOs and dismiss any xDBC errors that weren't already dismissed
			tell application "System Events"
				tell application process "FileMaker Pro Advanced"
					keystroke "i" using command down
				end tell
			end tell
			delay 1
			fmGUI_ManageDb_DismissXDBCDialog({})

			-- zoom back in
			tell application "System Events"
				tell application process "FileMaker Pro Advanced"
					set zoomField to text field 1 of tab group 1 of window 1
					set focused of zoomField to true
					set value of zoomField to "100"
				end tell
			end tell

			return true
		end if
	on error errMsg number errNum
		error "Couldn't open manage DB - " & errMsg number errNum
	end try

end fmGUI_ManageDb_Open

--------------------
-- END OF CODE
--------------------

on fmGUI_AppFrontMost(prefs)
	tell application "Finder" to set handlerPath to ((container of (path to me)) as text) & "fmGUI_AppFrontMost" & ".scpt"
	tell (load script alias handlerPath) to return fmGUI_AppFrontMost(prefs)
end fmGUI_AppFrontMost

on fmGUI_ManageDb_DismissXDBCDialog(prefs)
	tell application "Finder" to set handlerPath to ((container of (path to me)) as text) & "fmGUI_ManageDb_DismissXDBCDialog" & ".scpt"
	tell (load script alias handlerPath) to return fmGUI_ManageDb_DismissXDBCDialog(prefs)
end

on fmGUI_ManageDb_GoToTab_Relationships(prefs)
	tell application "Finder" to set handlerPath to ((container of (path to me)) as text) & "fmGUI_ManageDb_GoToTab_Relationships" & ".scpt"
	tell (load script alias handlerPath) to return fmGUI_ManageDb_GoToTab_Relationships(prefs)
end

on fmGUI_Menu_OpenDB(prefs)
	tell application "Finder" to set handlerPath to ((container of (path to me)) as text) & "fmGUI_Menu_OpenDB" & ".scpt"
	tell (load script alias handlerPath) to return fmGUI_Menu_OpenDB(prefs)
end

on fmGUI_NameOfFrontmostWindow(prefs)
	tell application "Finder" to set handlerPath to ((container of (path to me)) as text) & "fmGUI_NameOfFrontmostWindow" & ".scpt"
	tell (load script alias handlerPath) to return fmGUI_NameOfFrontmostWindow(prefs)
end

-- fmGUI_ManageDb_Open(prefs)
-- Daniel A. Shockley, NYHTC
-- Open Manage Database

(*
HISTORY:
	1.4 - 2020-05-20 ( dshockley ): added multiple missing sub-handlers. Removed referfence to old sub-handler.
	1.3 - 2018-04-30 ( eshagdar ): get window name via handler.
	1.2 - added xDBC connection error trapping
	1.1 -
	1.0 - created

TODO:
	- 2015-06-03 ( eshagdar ): probably going to need to open manageDB via openManageDB script if the menu item fails

REQUIRES:
	fmGUI_AppFrontMost
	fmGUI_ManageDb_DismissXDBCDialog
	fmGUI_ManageDb_GoToTab_Relationships
	fmGUI_Menu_OpenDB
	fmGUI_NameOfFrontmostWindow
*)

on run
	fmGUI_ManageDb_Open({})
end run

--------------------
-- START OF CODE
--------------------

on fmGUI_ManageDb_Open(prefs)
	-- version 1.4

	try
		fmGUI_AppFrontMost()

		-- try to open Manage DB
		set windowName to fmGUI_NameOfFrontmostWindow()
		if windowName starts with "Manage Database for" then
			return true
		else
			fmGUI_Menu_OpenDB({})

			-- dismiss any initial xDBC connection errors
			fmGUI_ManageDb_DismissXDBCDialog({})

			-- go to the TOs tab and AGAIN dismiss any xDBC connections that failed to connect
			fmGUI_ManageDb_GoToTab_Relationships({})
			delay 1
			fmGUI_ManageDb_DismissXDBCDialog({})

			--zoom out to show all TOs and dismiss any xDBC errors that weren't already dismissed
			tell application "System Events"
				tell application process "FileMaker Pro Advanced"
					keystroke "i" using command down
				end tell
			end tell
			delay 1
			fmGUI_ManageDb_DismissXDBCDialog({})

			-- zoom back in
			tell application "System Events"
				tell application process "FileMaker Pro Advanced"
					set zoomField to text field 1 of tab group 1 of window 1
					set focused of zoomField to true
					set value of zoomField to "100"
					key code 48 (* tab out of the zoom field *)
				end tell
			end tell

			return true
		end if
	on error errMsg number errNum
		error "Couldn't open manage DB - " & errMsg number errNum
	end try

end fmGUI_ManageDb_Open

--------------------
-- END OF CODE
--------------------

on fmGUI_AppFrontMost()
	tell application "Finder" to set handlerPath to ((container of (path to me)) as text) & "fmGUI_AppFrontMost" & ".scpt"
	tell (load script alias handlerPath) to return fmGUI_AppFrontMost()
end fmGUI_AppFrontMost

on fmGUI_ManageDb_DismissXDBCDialog(prefs)
	tell application "Finder" to set handlerPath to ((container of (path to me)) as text) & "fmGUI_ManageDb_DismissXDBCDialog" & ".scpt"
	tell (load script alias handlerPath) to return fmGUI_ManageDb_DismissXDBCDialog(prefs)
end fmGUI_ManageDb_DismissXDBCDialog

on fmGUI_ManageDb_GoToTab_Relationships(prefs)
	tell application "Finder" to set handlerPath to ((container of (path to me)) as text) & "fmGUI_ManageDb_GoToTab_Relationships" & ".scpt"
	tell (load script alias handlerPath) to return fmGUI_ManageDb_GoToTab_Relationships(prefs)
end fmGUI_ManageDb_GoToTab_Relationships

on fmGUI_Menu_OpenDB(prefs)
	tell application "Finder" to set handlerPath to ((container of (path to me)) as text) & "fmGUI_Menu_OpenDB" & ".scpt"
	tell (load script alias handlerPath) to return fmGUI_Menu_OpenDB(prefs)
end fmGUI_Menu_OpenDB

on fmGUI_NameOfFrontmostWindow()
	tell application "Finder" to set handlerPath to ((container of (path to me)) as text) & "fmGUI_NameOfFrontmostWindow" & ".scpt"
	tell (load script alias handlerPath) to return fmGUI_NameOfFrontmostWindow()
end fmGUI_NameOfFrontmostWindow

fix sub-handler params

fix sub-handler params


on is_running(appName)
	tell application "System Events" to (name of processes) contains appName
end is_running

set nl to "
"

if is_running("Hermes") then
	tell application "Hermes"
		return "__RUNNING__" & nl &
			current song's title & nl &
			current song's artist & nl &
			current song's album & nl &
			current song's artwork URL
	end tell
else
	return "__NOT_RUNNING__"
end if

on is_running(appName)
	tell application "System Events" to (name of processes) contains appName
end is_running

set nl to "
"

if is_running("Hermes") then
	tell application "Hermes"
		return "__RUNNING__" & nl & ¬
			current song's title & nl & ¬
			current song's artist & nl & ¬
			current song's album & nl & ¬
			current song's artwork URL
	end tell
else
	return "__NOT_RUNNING__"
end if

Convert status.applescript to UTF-8

Convert status.applescript to UTF-8


property thumbSize : 480

on getImages(f)
  tell application "Finder" to return (files of folder f) as alias list
end getImages

on run argv
  set keynotePresentation to item 1 of argv
  set tmpKeynotePresentation to item 2 of argv

  set keynotePresentation to (POSIX file keynotePresentation) as alias
  set tmpkeynotePresentation to (POSIX file keynotePresentation) as alias

  tell application "Keynote"
    activate
    open tmpkeynotePresentation

    if playing is true then stop the front document
    set documentName to the name of the front document
    if documentName ends with ".key" then set documentName to text 1 thru -5 of documentName

    tell application "Finder"
      set keynoteContainer to (container of keynotePresentation) as alias
      if not (exists folder documentName of folder keynoteContainer)
        make new folder at keynoteContainer with properties {name:documentName}
      end if
      set the targetFolder to folder documentName of folder keynoteContainer
      set the targetFolderHFSPath to targetFolder as string
    end tell

    export front document as slide images to file targetFolderHFSPath with properties {image format: JPEG}
    set jpegs to my getImages(targetFolderHFSPath)
    repeat with thisJPEG in jpegs
      try
        tell application "Image Events"
          launch
          set this_image to open thisJPEG
          scale this_image to size thumbSize
          save this_image with icon
          close this_image
        end tell
        on error error_message
          display dialog error_message
      end try
    end repeat

    close front document without saving
  end tell
  return POSIX path of keynoteContainer
end run

-- thumbscrew.scpt
-- usage: thumbscript.scpt <path_to_root_dir> <path_to_keynotePresentation> <presentation_name>
--
-- Will create scaled thumbnails of length `thumbSize` in the directory
-- <path_to_root_dir>/.keynote/<presentation>
property thumbSize : 480
property thumbnailDir: "keynotes"

on getImages(f)
  tell application "Finder" to return (files of folder f) as alias list
end getImages

on run argv
  set gitRoot to item 1 of argv
  set tmpFile to item 2 of argv
  set documentName to item 3 of argv
  if documentName ends with ".key" then set documentName to text 1 thru -5 of documentName

  set gitRoot to posix file (POSIX path of (gitRoot as text) & "/" & thumbnailDir) as alias
  set tmpFile to (POSIX file tmpFile) as alias

  tell application "Keynote"
    activate
    open tmpFile

    if playing is true then stop the front document

    tell application "Finder"
      if not (exists folder documentName of folder gitRoot)
        make new folder at gitRoot with properties {name:documentName}
      end if
      set the targetFolder to folder documentName of folder gitRoot
      set the targetFolderHFSPath to targetFolder as string
    end tell

    export front document as slide images to file targetFolderHFSPath with properties {image format: JPEG}
    set jpegs to my getImages(targetFolderHFSPath)
    repeat with thisJPEG in jpegs
      try
        tell application "Image Events"
          launch
          set this_image to open thisJPEG
          scale this_image to size thumbSize
          save this_image with icon
          close this_image
        end tell
        on error error_message
          display dialog error_message
      end try
    end repeat

    close front document without saving
  end tell
  return POSIX path of gitRoot
end run

update applescript to work with a filter


#!/usr/bin/env osascript

-- see http://frantic.im/notify-on-completion
on run argv
  tell application "System Events"
    set frontApp to name of first application process whose frontmost is true
    if frontApp is not "HyperTerm" then
      set notifTitle to item 1 of argv
      set notifBody to "succeded"
      set errorCode to item 2 of argv
      if errorCode is not "0"
        set notifBody to "failed with error code " & errorCode
      end if
      display notification notifBody with title notifTitle
    end if
  end tell
end run

#!/usr/bin/env osascript

-- see http://frantic.im/notify-on-completion
on run argv
  tell application "System Events"
    set frontApp to name of first application process whose frontmost is true
    if frontApp is not "iTerm2" then
      set notifTitle to item 1 of argv
      set notifBody to "succeded"
      set errorCode to item 2 of argv
      if errorCode is not "0"
        set notifBody to "failed with error code " & errorCode
      end if
      display notification notifBody with title notifTitle
    end if
  end tell
end run

Revert ":wrench: notifyme script: use HyperTerm instead of iTerm"

This reverts commit 17cba7446fc7fffc5bb5d09646fc11f3a5a68bdc.


--
--  DASAppDelegate.applescript
--  itunes-concatenator
--
--  Created by David Schlachter on 2014-08-26.
--  Copyright (c) 2014 Red Eft Software. All rights reserved.
--

-- via http://macscripter.net/viewtopic.php?pid=173787 ; apparently needed for using arrays

script DASAppDelegate
	property parent : class "NSObject"

    global these_files, these_times, these_titles, the_index, the_pipes, theCounter, cmdPrefix

	-- IBOutlets
	property window : missing value
    property trackTable : missing value
    property catName : missing value
    property catArtist : missing value
    property catAlbum : missing value
    property catComposer : missing value
    property catGenre : missing value
    property catTrack : missing value
    property catTracks : missing value
    property catDisc : missing value
    property catDiscs : missing value
    property catAlbumArtist : missing value
    property catYear : missing value

    -- Again, per macscripter, we'll set up bindings for the options
    property pcatName : ""
    property pcatArtist : ""
    property pcatAlbum : ""
    property pcatComposer : ""
    property pcatGenre : ""
    property pcatTrack : ""
    property pcatTracks : ""
    property pcatDisc : ""
    property pcatDiscs : ""
    property pcatAlbumArtist : ""
    property pcatYear : ""

    -- Empty strings for each file name and location
    property pEachName : ""
    property pEachLocation : ""

    property these_titles : {}
    property these_files : {}
    property these_times: {}
    property the_index: {}
    property the_pipes: {}

    property theCounter : ""
    property cmdPrefix : "if [[ -r /etc/profile ]];then . /etc/profile;fi;if [[ -r ~/.bashrc ]];then . ~/.bashrc;fi;if [[ -r ~/.bash_profile ]];then . ~/.bash_profile;fi;"

    on awakeFromNib()
        --
        -- Check for FFMPEG and MP4v2
        --
        -- (This works, but it's ugly!)
        --
        --
        try
            do shell script cmdPrefix & " if [ -x \"`/usr/bin/which ffmpeg`\" ];then exit 0;else exit 1;fi"
        on error number error_number
            display dialog "You must install FFMPEG and MP4v2 to continue. \n\nYou may have to install Xcode Command Line Tools and Homebrew first. If you continue, we'll attempt to install them for you if they are not already present. \n\nIf you have already installed FFMPEG and MP4v2, ensure that they are in your bash path." buttons {"Quit","Install"} default button 2
            If button returned of result is "Install" then
                try
                    tell application "Terminal"
                        -- TODO: This should be cleaner -- Terminal in front, only one window, focus back to the cat'er afterwards
                        set newTab to do script cmdPrefix & "if [[ -x `which brew` ]];then brew install ffmpeg;else /usr/bin/ruby -e \"$(/usr/bin/curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)\";brew install ffmpeg mp4v2;fi"
                        delay 4
                        repeat
                            delay 0.1
                            if not busy of newTab then exit repeat
                        end repeat
                    end tell
                     -- TODO: This needs a better test, i.e., check if ffmpeg is actually accessible on the path
                    display dialog "FFMPEG was successfully installed"
                    -- TODO: This should actually work! (Bring us back to the foreground)
                    activate current application
                on error number error_number
                    display dialog "FFMPEG did not successfully install"
                end try
            end If
            If button returned of result is "Quit" then
                -- Fix!
                current application's NSApp's terminate()
            end If
        end try
    end awakeFromNib

    on btnGetTracks_(sender)
        -- Code to add iTunes tracks to our list
        -- via http://dougscripts.com/itunes/itinfo/info02.php and http://www.randomsequence.com/articles/applescript-to-send-selected-itunes-tracks-using-mail/
        tell application "iTunes"
            set these_titles to {}
            set these_times to {}
            set these_files to {}
            set the_index to {}
            if selection is not {} then -- there ARE tracks selected...
                set mySelection to selection
                set i to 1
                repeat with aTrack in mySelection
                    if class of aTrack is file track then
                        set end of these_titles to ((name of aTrack) as string)
                        set end of these_times to ((time of aTrack) as string)
                        set end of these_files to (posix path of (get location of aTrack))
                        set end of the_index to (count of these_titles)
                        -- Get metadata from the first track
                        if i is 1 then
                            set pcatArtist to ((artist of aTrack) as string)
                            set pcatAlbum to ((album of aTrack) as string)
                            set pcatComposer to ((composer of aTrack) as string)
                            set pcatGenre to ((genre of aTrack) as string)
                            set pcatDisc to ((disc number of aTrack) as string)
                            set pcatDiscs to ((disc count of aTrack) as string)
                            set pcatAlbumArtist to ((album artist of aTrack) as string)
                            set pcatYear to ((year of aTrack) as string)
                        end if
                        set i to (i + 1)
                    end if
                end repeat
            end if
        end tell
        -- Display the songs to be concatenated
        -- via http://stackoverflow.com/questions/25537750/setstringvalue-with-applescript-list
        set olddelimeters to AppleScript's text item delimiters
        set AppleScript's text item delimiters to "\n"
        set disp_titles to these_titles as string
        trackTable's setStringValue_(disp_titles)
        set AppleScript's text item delimiters to olddelimeters
        -- Update the default metadata
        catArtist's setStringValue_(pcatArtist)
        catAlbum's setStringValue_(pcatAlbum)
        catComposer's setStringValue_(pcatComposer)
        catGenre's setStringValue_(pcatGenre)
        catDisc's setStringValue_(pcatDisc)
        catDiscs's setStringValue_(pcatDiscs)
        catAlbumArtist's setStringValue_(pcatAlbumArtist)
        catYear's setStringValue_(pcatYear)
    end btnGetTracks_

    on btnConcatenate_(sender)
        -- Update the metadata variables with the user's input
        set pcatName to catName's stringValue()
        set pcatArtist to catArtist's stringValue()
        set pcatAlbum to catAlbum's stringValue()
        set pcatComposer to catComposer's stringValue()
        set pcatGenre to catGenre's stringValue()
        set pcatTrack to catTrack's stringValue()
        set pcatTracks to catTracks's stringValue()
        set pcatDisc to catDisc's stringValue()
        set pcatDiscs to catDiscs's stringValue()
        set pcatAlbumArtist to catAlbumArtist's stringValue()
        set pcatYear to catYear's stringValue()
        set the_pipes to {}
        repeat with theIndex in the_index
            -- TODO: Needs error checking!
            -- TODO: We need to check what kind of audio files we have, then adjust accordingly
            do shell script (cmdPrefix & "ffmpeg -i \"" & (item theIndex of these_files as text) & "\" -c copy -bsf:v h264_mp4toannexb -f mpegts /private/tmp/concat" & theIndex & ".ts 2> /dev/null" as text)
            log ("Processed file number" & theIndex) as text
            set end of the_pipes to ("/private/tmp/concat" & theIndex & ".ts" as text)
        end repeat
        -- Run the actual concatenation command in ffmpeg (for mp4/AAC files only!)
        -- via https://trac.ffmpeg.org/wiki/How%20to%20concatenate%20(join,%20merge)%20media%20files
        set olddelimeters to AppleScript's text item delimiters
        set AppleScript's text item delimiters to "|"
        set disp_thepipes to the_pipes as string
        do shell script (cmdPrefix & "ffmpeg -f mpegts -i \"concat:" & (disp_thepipes as text) & "\" -c copy -bsf:a aac_adtstoasc /private/tmp/cat.mp4")
        set AppleScript's text item delimiters to olddelimeters
        -- Now let's create the chapter file
        repeat with theIndex in the_index
            if theIndex < 2 then
                do shell script ("/bin/echo \"00:00:00.000 " & (item theIndex of these_titles as text) & "\" > /private/tmp/cat.chapters.txt" as text)
                set theCounter to (do shell script (cmdPrefix & "ffprobe -loglevel panic -show_streams /private/tmp/concat" & (theIndex as text) & ".ts | egrep -m 1 'duration=[0-9]+\\.' | sed 's/duration=\\([0-9]*[0-9]\\.[0-9]*\\)/\\1/'" as text) as string)
                set theCounter to (do shell script ("/bin/echo $(/usr/bin/printf %.$2f $(/bin/echo \"`/usr/bin/printf %.3f " & theCounter & "` * 1000\" | /usr/bin/bc))") as string)
            else
                set theDateStamp to do shell script (cmdPrefix & "t="& (theCounter as text) & ";((msec=t%1000, t/=1000, sec=t%60, t/=60, min=t%60, hrs=t/60));timestamp=$(printf \"%02d:%02d:%02d.%03d\" $hrs $min $sec $msec);/bin/echo $timestamp" as text)
                do shell script ("/bin/echo \"" & (theDateStamp as text) & " " & (item theIndex of these_titles as text) & "\" >> /private/tmp/cat.chapters.txt" as text)
                set theNewCounter to do shell script ((cmdPrefix & "ffprobe -loglevel panic -show_streams /private/tmp/concat" & (theIndex as text) & ".ts | egrep -m 1 'duration=[0-9]+\\.' | sed 's/duration=\\([0-9]*[0-9]\\.[0-9]*\\)/\\1/'" as text) as string)
                set theNewCounter to do shell script ("/bin/echo $(/usr/bin/printf %.$2f $(/bin/echo \"`/usr/bin/printf %.3f " & theNewCounter & "` * 1000\" | /usr/bin/bc))") as string
                log "theNewCounter is " & theNewCounter
                set theCounter to (theCounter + theNewCounter)
                log ("Post-addition, theCounter is " & theCounter) as text
            end if
        end repeat
        -- Chapterize cat.mp4
        do shell script (cmdPrefix & "mp4chaps -i /private/tmp/cat.mp4" as text)
        -- Add tags
        do shell script (cmdPrefix & "mp4tags -song \"" & pcatName & "\" -album \"" &  pcatAlbum & "\" -artist \"" &  pcatArtist & "\" -writer \"" &  pcatComposer & "\" -genre \"" &  pcatGenre & "\" -track \"" &  pcatTrack & "\" -tracks \"" &  pcatTracks & "\" -disk \"" &  pcatDisc & "\" -disks \"" &  pcatDiscs & "\" -albumartist \"" & pcatAlbumArtist & "\" -year \"" & pcatYear & "\" /private/tmp/cat.mp4" as text)
        -- Add the finished track to iTunes
        do shell script "/bin/mv /private/tmp/cat.mp4 /private/tmp/cat.m4a"
        tell application "iTunes"
                add file ":private:tmp:cat.m4a"
        end tell
        -- Clean up
        do shell script "/bin/rm /private/tmp/concat* /private/tmp/cat.chapters.txt /private/tmp/cat.m4a"
        set theCounter to ""
    end btnConcatenate_

	on applicationWillFinishLaunching_(aNotification)
		-- Insert code here to initialize your application before any files are opened
	end applicationWillFinishLaunching_

	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits
		return current application's NSTerminateNow
	end applicationShouldTerminate_

end script

--
--  DASAppDelegate.applescript
--  itunes-concatenator
--
--  Created by David Schlachter on 2014-08-26.
--  Copyright (c) 2014 Red Eft Software. All rights reserved.
--

-- via http://macscripter.net/viewtopic.php?pid=173787 ; apparently needed for using arrays

script DASAppDelegate
	property parent : class "NSObject"

    global these_files, these_times, these_titles, the_index, the_pipes, theCounter, cmdPrefix

	-- IBOutlets
	property window : missing value
    property trackTable : missing value
    property catName : missing value
    property catArtist : missing value
    property catAlbum : missing value
    property catComposer : missing value
    property catGenre : missing value
    property catTrack : missing value
    property catTracks : missing value
    property catDisc : missing value
    property catDiscs : missing value
    property catAlbumArtist : missing value
    property catYear : missing value

    -- Again, per macscripter, we'll set up bindings for the options
    property pcatName : ""
    property pcatArtist : ""
    property pcatAlbum : ""
    property pcatComposer : ""
    property pcatGenre : ""
    property pcatTrack : ""
    property pcatTracks : ""
    property pcatDisc : ""
    property pcatDiscs : ""
    property pcatAlbumArtist : ""
    property pcatYear : ""

    -- Empty strings for each file name and location
    property pEachName : ""
    property pEachLocation : ""

    property these_titles : {}
    property these_files : {}
    property these_times: {}
    property the_index: {}
    property the_pipes: {}

    property theCounter : ""
    property cmdPrefix : "if [[ -r /etc/profile ]];then . /etc/profile;fi;if [[ -r ~/.bashrc ]];then . ~/.bashrc;fi;if [[ -r ~/.bash_profile ]];then . ~/.bash_profile;fi;"

    on awakeFromNib()
        --
        -- Check for FFMPEG and MP4v2
        --
        -- (This works, but it's ugly!)
        --
        --
        try
            do shell script cmdPrefix & " if [ -x \"`/usr/bin/which ffmpeg`\" ];then exit 0;else exit 1;fi"
        on error number error_number
            display dialog "You must install FFMPEG and MP4v2 to continue. \n\nYou may have to install Xcode Command Line Tools and Homebrew first. If you continue, we'll attempt to install them for you if they are not already present. \n\nIf you have already installed FFMPEG and MP4v2, ensure that they are in your bash path." buttons {"Quit","Install"} default button 2
            If button returned of result is "Install" then
                try
                    tell application "Terminal"
                        -- TODO: This should be cleaner -- Terminal in front, only one window, focus back to the cat'er afterwards
                        set newTab to do script cmdPrefix & "if [[ -x `which brew` ]];then brew install ffmpeg;else /usr/bin/ruby -e \"$(/usr/bin/curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)\";brew install ffmpeg mp4v2;fi"
                        delay 4
                        repeat
                            delay 0.1
                            if not busy of newTab then exit repeat
                        end repeat
                    end tell
                     -- TODO: This needs a better test, i.e., check if ffmpeg is actually accessible on the path
                    display dialog "FFMPEG was successfully installed"
                    -- TODO: This should actually work! (Bring us back to the foreground)
                    activate current application
                on error number error_number
                    display dialog "FFMPEG did not successfully install"
                end try
            end If
            If button returned of result is "Quit" then
                -- Fix!
                current application's NSApp's terminate()
            end If
        end try
    end awakeFromNib

    on btnGetTracks_(sender)
        -- Code to add iTunes tracks to our list
        -- via http://dougscripts.com/itunes/itinfo/info02.php and http://www.randomsequence.com/articles/applescript-to-send-selected-itunes-tracks-using-mail/
        tell application "iTunes"
            set these_titles to {}
            set these_times to {}
            set these_files to {}
            set the_index to {}
            if selection is not {} then -- there ARE tracks selected...
                set mySelection to selection
                set i to 1
                repeat with aTrack in mySelection
                    if class of aTrack is file track then
                        set end of these_titles to ((name of aTrack) as string)
                        set end of these_times to ((time of aTrack) as string)
                        set end of these_files to (posix path of (get location of aTrack))
                        set end of the_index to (count of these_titles)
                        -- Get metadata from the first track
                        if i is 1 then
                            set pcatArtist to ((artist of aTrack) as string)
                            set pcatAlbum to ((album of aTrack) as string)
                            set pcatComposer to ((composer of aTrack) as string)
                            set pcatGenre to ((genre of aTrack) as string)
                            set pcatDisc to ((disc number of aTrack) as string)
                            set pcatDiscs to ((disc count of aTrack) as string)
                            set pcatAlbumArtist to ((album artist of aTrack) as string)
                            set pcatYear to ((year of aTrack) as string)
                        end if
                        set i to (i + 1)
                    end if
                end repeat
            end if
        end tell
        -- Display the songs to be concatenated
        -- via http://stackoverflow.com/questions/25537750/setstringvalue-with-applescript-list
        set olddelimeters to AppleScript's text item delimiters
        set AppleScript's text item delimiters to "\n"
        set disp_titles to these_titles as string
        trackTable's setStringValue_(disp_titles)
        set AppleScript's text item delimiters to olddelimeters
        -- Update the default metadata
        catArtist's setStringValue_(pcatArtist)
        catAlbum's setStringValue_(pcatAlbum)
        catComposer's setStringValue_(pcatComposer)
        catGenre's setStringValue_(pcatGenre)
        catDisc's setStringValue_(pcatDisc)
        catDiscs's setStringValue_(pcatDiscs)
        catAlbumArtist's setStringValue_(pcatAlbumArtist)
        catYear's setStringValue_(pcatYear)
        -- Reset the name and track fields
        catName's setStringValue_("")
        catTrack's setStringValue_("")
        catTracks's setStringValue_("")
    end btnGetTracks_

    on btnConcatenate_(sender)
        -- Update the metadata variables with the user's input
        set pcatName to catName's stringValue()
        set pcatArtist to catArtist's stringValue()
        set pcatAlbum to catAlbum's stringValue()
        set pcatComposer to catComposer's stringValue()
        set pcatGenre to catGenre's stringValue()
        set pcatTrack to catTrack's stringValue()
        set pcatTracks to catTracks's stringValue()
        set pcatDisc to catDisc's stringValue()
        set pcatDiscs to catDiscs's stringValue()
        set pcatAlbumArtist to catAlbumArtist's stringValue()
        set pcatYear to catYear's stringValue()
        set the_pipes to {}
        repeat with theIndex in the_index
            -- TODO: Needs error checking!
            -- TODO: We need to check what kind of audio files we have, then adjust accordingly
            do shell script (cmdPrefix & "ffmpeg -i \"" & (item theIndex of these_files as text) & "\" -c copy -bsf:v h264_mp4toannexb -f mpegts /private/tmp/concat" & theIndex & ".ts 2> /dev/null" as text)
            log ("Processed file number" & theIndex) as text
            set end of the_pipes to ("/private/tmp/concat" & theIndex & ".ts" as text)
        end repeat
        -- Run the actual concatenation command in ffmpeg (for mp4/AAC files only!)
        -- via https://trac.ffmpeg.org/wiki/How%20to%20concatenate%20(join,%20merge)%20media%20files
        set olddelimeters to AppleScript's text item delimiters
        set AppleScript's text item delimiters to "|"
        set disp_thepipes to the_pipes as string
        do shell script (cmdPrefix & "ffmpeg -f mpegts -i \"concat:" & (disp_thepipes as text) & "\" -c copy -bsf:a aac_adtstoasc /private/tmp/cat.mp4")
        set AppleScript's text item delimiters to olddelimeters
        -- Now let's create the chapter file
        repeat with theIndex in the_index
            if theIndex < 2 then
                do shell script ("/bin/echo \"00:00:00.000 " & (item theIndex of these_titles as text) & "\" > /private/tmp/cat.chapters.txt" as text)
                set theCounter to (do shell script (cmdPrefix & "ffprobe -loglevel panic -show_streams /private/tmp/concat" & (theIndex as text) & ".ts | egrep -m 1 'duration=[0-9]+\\.' | sed 's/duration=\\([0-9]*[0-9]\\.[0-9]*\\)/\\1/'" as text) as string)
                set theCounter to (do shell script ("/bin/echo $(/usr/bin/printf %.$2f $(/bin/echo \"`/usr/bin/printf %.3f " & theCounter & "` * 1000\" | /usr/bin/bc))") as string)
            else
                set theDateStamp to do shell script (cmdPrefix & "t="& (theCounter as text) & ";((msec=t%1000, t/=1000, sec=t%60, t/=60, min=t%60, hrs=t/60));timestamp=$(printf \"%02d:%02d:%02d.%03d\" $hrs $min $sec $msec);/bin/echo $timestamp" as text)
                do shell script ("/bin/echo \"" & (theDateStamp as text) & " " & (item theIndex of these_titles as text) & "\" >> /private/tmp/cat.chapters.txt" as text)
                set theNewCounter to do shell script ((cmdPrefix & "ffprobe -loglevel panic -show_streams /private/tmp/concat" & (theIndex as text) & ".ts | egrep -m 1 'duration=[0-9]+\\.' | sed 's/duration=\\([0-9]*[0-9]\\.[0-9]*\\)/\\1/'" as text) as string)
                set theNewCounter to do shell script ("/bin/echo $(/usr/bin/printf %.$2f $(/bin/echo \"`/usr/bin/printf %.3f " & theNewCounter & "` * 1000\" | /usr/bin/bc))") as string
                log "theNewCounter is " & theNewCounter
                set theCounter to (theCounter + theNewCounter)
                log ("Post-addition, theCounter is " & theCounter) as text
            end if
        end repeat
        -- Chapterize cat.mp4
        do shell script (cmdPrefix & "mp4chaps -i /private/tmp/cat.mp4" as text)
        -- Add tags
        do shell script (cmdPrefix & "mp4tags -song \"" & pcatName & "\" -album \"" &  pcatAlbum & "\" -artist \"" &  pcatArtist & "\" -writer \"" &  pcatComposer & "\" -genre \"" &  pcatGenre & "\" -track \"" &  pcatTrack & "\" -tracks \"" &  pcatTracks & "\" -disk \"" &  pcatDisc & "\" -disks \"" &  pcatDiscs & "\" -albumartist \"" & pcatAlbumArtist & "\" -year \"" & pcatYear & "\" /private/tmp/cat.mp4" as text)
        -- Add the finished track to iTunes
        do shell script "/bin/mv /private/tmp/cat.mp4 /private/tmp/cat.m4a"
        tell application "iTunes"
                add file ":private:tmp:cat.m4a"
        end tell
        -- Clean up
        do shell script "/bin/rm /private/tmp/concat* /private/tmp/cat.chapters.txt /private/tmp/cat.m4a"
        set theCounter to ""
    end btnConcatenate_

	on applicationWillFinishLaunching_(aNotification)
		-- Insert code here to initialize your application before any files are opened
	end applicationWillFinishLaunching_

	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits
		return current application's NSTerminateNow
	end applicationShouldTerminate_

end script

Reset the name and track w/new batches

Reset the name and track w/new batches