summaryrefslogtreecommitdiffstats
path: root/tmac/s.tmac
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tmac/s.tmac2177
1 files changed, 2177 insertions, 0 deletions
diff --git a/tmac/s.tmac b/tmac/s.tmac
new file mode 100644
index 0000000..bdf36b8
--- /dev/null
+++ b/tmac/s.tmac
@@ -0,0 +1,2177 @@
+.ig
+
+s.tmac
+
+Copyright (C) 1989-2021 Free Software Foundation, Inc.
+ Written by James Clark (jjc@jclark.com)
+
+This file is part of groff.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+..
+.if !\n(.g \
+. ab groff ms macros require groff extensions; aborting
+.
+.if \n(.C \
+. ab groff ms macros do not work in compatibility mode; aborting
+.
+.\" See if already loaded.
+.if r GS .nx
+.nr GS 1
+.
+.mso devtag.tmac
+.nr s@devtag-needs-end-of-heading 0
+.nr s@devtag-needs-end-of-title 0
+.
+.\" Define a string for use in diagnostic messages.
+.ds @s s.tmac\"
+.
+.de @diag
+. ds *file \" empty
+. ds *line \" empty
+. if !'\\n[.F]'' .ds *file \\n[.F]:\"
+. if !'\\n[.c]'0' .ds *line \\n[.c]:\"
+. tm \*[@s]:\\*[*file]\\*[*line] \\$*
+. rm *file
+. rm *line
+..
+.
+.de @error
+. @diag error: \\$*
+..
+.
+.de @warning
+. @diag warning: \\$*
+..
+.
+.de @nop
+..
+.
+.de @not-implemented
+.@error sorry, .\\$0 not implemented
+.als \\$0 @nop
+..
+.
+.\" documented Unix Version 7 ms macros that we don't implement
+.als EG @not-implemented \" engineer's notes
+.als IM @not-implemented \" internal memorandum
+.als MF @not-implemented \" memorandum for file
+.als MR @not-implemented \" memorandum for record
+.als TM @not-implemented \" technical memorandum
+.als TR @not-implemented \" technical report
+.als AT @not-implemented \" attachments
+.als CS @not-implemented \" cover sheet info for `TM` documents
+.als CT @not-implemented \" copies to
+.als OK @not-implemented \" "other keywords" for `TM` documents
+.als SG @not-implemented \" signatures for `TM` documents
+.als HO @not-implemented \" Holmdel
+.als IH @not-implemented \" Naperville (Indian Hill)
+.als MH @not-implemented \" Murray Hill
+.als PY @not-implemented \" Piscataway
+.als WH @not-implemented \" Whippany
+.als UX @not-implemented \" Unix w/ footnote trademark
+.
+.\" 4.2BSD ms macros documented by Tuthill 1983 that we don't implement
+.\"als TM @not-implemented \" thesis mode (already handled)
+.\"als CT @not-implemented \" chapter title for thesis (already handled)
+.
+.\" Wrap the .di request to save the name of the file being processed
+.\" when a diversion is started. This aids diagnostics when diversions
+.\" are still open after input has been processed and \n[.F] is empty.
+.als @divert di
+.de di
+. if \\n[.$] .ds @last-file-seen \\n[.F]\"
+. @divert \\$*
+..
+.
+.de @init
+.if !rPO .nr PO \\n(.o
+.\" a non-empty environment
+.ev ne
+\c
+.ev
+.ev nf
+'nf
+.ev
+..
+.ds REFERENCES References
+.ds ABSTRACT ABSTRACT
+.ds TOC Table of Contents
+.ds MONTH1 January
+.ds MONTH2 February
+.ds MONTH3 March
+.ds MONTH4 April
+.ds MONTH5 May
+.ds MONTH6 June
+.ds MONTH7 July
+.ds MONTH8 August
+.ds MONTH9 September
+.ds MONTH10 October
+.ds MONTH11 November
+.ds MONTH12 December
+.ds MO \E*[MONTH\n[mo]]
+.ds DY \n[dy] \*[MO] \n[year]
+.de ND
+.if \\n[.$] .ds DY "\\$*
+..
+.de DA
+.if \\n[.$] .ds DY "\\$*
+.ds CF \\*[DY]
+..
+.\" print an error message and then try to recover
+.de @error-recover
+.@error \\$@ (recovering)
+.nr *pop-count 0
+.while !'\\n(.z'' \{\
+. \"@warning automatically terminating diversion \\n(.z
+. ie d @div-end!\\n(.z .@div-end!\\n(.z
+. el .*div-end-default
+. nr *pop-count +1
+. \" ensure that we don't loop forever
+. if \\n[*pop-count]>20 .ab \*[@s]: fatal error: recovery failed
+.\}
+.while !'\\n[.ev]'0' .ev
+.par@reset-env
+.par@reset
+..
+.de *div-end-default
+.ds *last-div \\n(.z
+.br
+.di
+.ev nf
+.\\*[*last-div]
+.ev
+..
+.\" ****************************
+.\" ******** module cov ********
+.\" ****************************
+.\" Cover sheet and first page.
+.de cov*err-not-after-first-page
+.@error .\\$0 is not allowed after the first page has started
+..
+.de cov*err-not-before-tl
+.@error .\\$0 is not allowed before .TL
+..
+.de cov*err-not-again
+.@error .\\$0 is not allowed more than once
+..
+.de cov*err-not-after-ab
+.@error .\\$0 is not allowed after first .AB, .LP, .PP, .IP, .SH or .NH
+..
+.als AU cov*err-not-before-tl
+.als AI cov*err-not-before-tl
+.als AB cov*err-not-before-tl
+.de cov*first-page-init
+.\" Invoked by '.wh 0' trap on first page.
+.\" We should not come here again, but at short page length,
+.\" recursion may occur; remove trap and macro to avoid it.
+.ch cov*first-page-init
+.rm cov*first-page-init
+.if !'\\n[.ev]'0' \{\
+. ds cov*msg must be in top-level environment, not '\\n[.ev]',\"
+. as cov*msg " when first page is started\"
+. @error \\*[cov*msg]
+. rm cov*msg
+.\}
+.par@init
+.als RP cov*err-not-after-first-page
+.@init
+.ie \\n[cov*use-rp-format] \{\
+. pg@cs-top
+. als FS cov*FS
+. als FE cov*FE
+.\}
+.el \{\
+. pg@top
+. als FS @FS
+. als FE @FE
+.\}
+.wh 0 pg@top
+.CHECK-FOOTER-AND-KEEP
+..
+.wh 0 cov*first-page-init
+.\" This handles the case where FS occurs before TL or LP.
+.de FS
+.br
+\\*[FS]\\
+..
+.nr cov*use-rp-format 0
+.\" If we add more cover page formats, these behaviors and names could
+.\" be generalized.
+.nr cov*rp-no-repeat-info 0
+.nr cov*rp-no-renumber 0
+.\" report (AT&T: "released paper") document type
+.de RP
+.nr cov*use-rp-format 1
+.while \\n[.$] \{\
+. if '\\$1'no' .nr cov*rp-no-repeat-info 1
+. if '\\$1'no-repeat-info' .nr cov*rp-no-repeat-info 1
+. if '\\$1'no-renumber' .nr cov*rp-no-renumber 1
+. shift
+.\}
+.if rPO .po \\n(POu
+..
+.de TL
+.br
+.als TL cov*err-not-again
+.rn @AB AB
+.rn @AU AU
+.rn @AI AI
+.di cov*tl-div
+.par@reset
+.ft B
+.ps +2
+.vs +3p
+.ll (u;\\n[LL]*5/6)
+.nr cov*n-au 0
+.DEVTAG-TL
+..
+.de @AU
+.par@reset
+.if !'\\n(.z'' \{\
+. br
+. di
+.\}
+.nr cov*n-au +1
+.di cov*au-div!\\n[cov*n-au]
+.nf
+.ft I
+.ie (\\n[PS] >= 1000) \
+. ps (\\n[PS]z / 1000u)
+.el \
+. ps \\n[PS]
+..
+.de @AI
+.par@reset
+.if !'\\n(.z'' \{\
+. br
+. di
+.\}
+.ie !\\n[cov*n-au] .@error .AI before .AU
+.el \{\
+. di cov*ai-div!\\n[cov*n-au]
+. nf
+. ft R
+. ie (\\n[PS] >= 1000) \
+. ps (\\n[PS]z / 1000u)
+. el \
+. ps \\n[PS]
+.\}
+..
+.
+.de LP
+.if !'\\n[.z]'' \{\
+. br
+. di
+.\}
+.br
+.cov*ab-init
+.cov*print
+.nop \\*[\\$0]\\
+..
+.
+.als IP LP
+.als PP LP
+.als XP LP
+.als QP LP
+.als RS LP
+.als NH LP
+.als SH LP
+.als MC LP
+.als RT LP
+.als XS LP
+.
+.de cov*ab-init
+.als cov*ab-init @nop
+.als LP @LP
+.als IP @IP
+.als PP @PP
+.als XP @XP
+.als RT @RT
+.als XS @XS
+.als SH @SH
+.als NH @NH
+.als QP @QP
+.als RS @RS
+.als RE @RE
+.als QS @QS
+.als QE @QE
+.als MC @MC
+.als EQ @EQ
+.als EN @EN
+.als PS @PS
+.als TS @TS
+.als AB cov*err-not-after-ab
+.als AU par@AU
+.als AI par@AI
+.als TL par@TL
+..
+.
+.de @AB
+.if !'\\n(.z'' \{\
+. br
+. di
+.\}
+.cov*ab-init
+.ie '\*(.T'html' \{\
+. cov*tl-au-print
+. als cov*tl-au-print @nop
+.\}
+.el .di cov*ab-div
+.par@ab-indent
+.par@reset
+.if !'\\$1'no' \{\
+. if '\*(.T'html' \{\
+. nf
+. sp
+. \}
+. ft I
+. ce 1
+\\*[ABSTRACT]
+. sp
+. ft R
+.\}
+.ns
+.@PP
+.if '\*(.T'html' \{\
+. cov*tl-au-print
+. als cov*tl-au-print @nop
+. par@reset-env
+. par@reset
+. cov*print
+.\}
+..
+.de AE
+.ie '\*(.T'html' \{\
+. als AE cov*err-not-again
+.\}
+.el \{\
+. ie '\\n(.z'cov*ab-div' \{\
+. als AE cov*err-not-again
+. br
+. di
+.\" nr cov*ab-height \\n[dn]
+. par@reset-env
+. par@reset
+. cov*print
+. \}
+. el .@error .AE without .AB
+.\}
+..
+.de @div-end!cov*ab-div
+.AE
+..
+.de cov*break-page
+.ie \\n[cov*rp-no-renumber] .bp
+.el .bp 1
+..
+.de cov*print
+.als cov*print @nop
+.ie d cov*tl-div \{\
+. ie \\n[cov*use-rp-format] .cov*rp-print
+. el .cov*draft-print
+.\}
+.el \{\
+. if \\n[cov*use-rp-format] \{\
+. @warning .RP format but no .TL
+. .cov*break-page
+. als FS @FS
+. als FE @FE
+. CHECK-FOOTER-AND-KEEP
+. \}
+. br
+.\}
+..
+.de cov*rp-print
+.nr cov*page-length \\n[.p]
+.pl 1000i
+.cov*tl-au-print
+.sp 3
+.if d cov*ab-div \{\
+. if !'\*(.T'html' .nf
+. cov*ab-div
+.\}
+.sp 3
+.par@reset
+\\*[DY]
+.br
+.if \\n[cov*fn-height] \{\
+. sp |(u;\\n[cov*page-length]-\\n[FM]\
+-\\n[cov*fn-height]-\\n[fn@sep-dist]>?\\n[nl])
+. fn@print-sep
+. ev nf
+. cov*fn-div
+. ev
+. ie \\n[cov*rp-no-repeat-info] .rm cov*fn-div
+. el \{\
+. rn cov*fn-div fn@overflow-div
+. nr fn@have-overflow 1
+. \}
+.\}
+.als FS @FS
+.als FE @FE
+.CHECK-FOOTER-AND-KEEP
+.\" If anything was printed below where the footer line is normally
+.\" printed, then that's an overflow.
+.if -\\n[FM]/2+1v+\\n[cov*page-length]<\\n[nl] \
+. @error cover sheet overflow
+.pl \\n[cov*page-length]u
+.cov*break-page
+.if !\\n[cov*rp-no-repeat-info] .cov*tl-au-print
+.rs
+.sp 1
+..
+.de cov*draft-print
+.cov*tl-au-print
+.if d cov*ab-div \{\
+. nf
+. sp 2
+. cov*ab-div
+.\}
+.sp 1
+..
+.de cov*tl-au-print
+.par@reset
+.nf
+.rs
+.sp 3
+.ce 9999
+.if d cov*tl-div \{\
+. cov*tl-div
+. DEVTAG-EO-TL
+.\}
+.nr cov*i 1
+.nr cov*sp 1v
+.while \\n[cov*i]<=\\n[cov*n-au] \{\
+. ie '\*(.T'html' .br
+. el .sp \\n[cov*sp]u
+. cov*au-div!\\n[cov*i]
+. ie d cov*ai-div!\\n[cov*i] \{\
+. sp .5v
+. cov*ai-div!\\n[cov*i]
+. nr cov*sp 1v
+. \}
+. el .nr cov*sp .5v
+. nr cov*i +1
+.\}
+.ce 0
+..
+.nr cov*fn-height 0
+.nr cov*in-fn 0
+.\" start of footnote on cover
+.de cov*FS
+.if \\n[cov*in-fn] \{\
+. @error nested .FS
+. FE
+.\}
+.nr cov*in-fn 1
+.ev fn
+.par@reset-env
+.da cov*fn-div
+.if !\\n[cov*fn-height] .ns
+.ie \\n[.$] .FP "\\$1" no
+.el .@LP
+..
+.de @div-end!cov*fn-div
+.cov*FE
+..
+.\" end of footnote on cover
+.de cov*FE
+.ie '\\n(.z'cov*fn-div' \{\
+. br
+. ev
+. di
+. nr cov*in-fn 0
+. nr cov*fn-height +\\n[dn]
+.\}
+.el .@error .FE without matching .FS
+..
+.\" ***************************
+.\" ******** module pg ********
+.\" ***************************
+.\" Page-level formatting.
+.\" > 0 if we have a footnote on the current page
+.nr pg@fn-flag 0
+.nr pg@colw 0
+.nr pg@fn-colw 0
+.nr HM 1i
+.nr FM 1i
+.ds LF
+.ds CF
+.ds RF
+.ds LH
+.ds CH -\En[%]-\"
+.ds RH
+.ds pg*OH '\E*[LH]'\E*[CH]'\E*[RH]'
+.ds pg*EH '\E*[LH]'\E*[CH]'\E*[RH]'
+.ds pg*OF '\E*[LF]'\E*[CF]'\E*[RF]'
+.ds pg*EF '\E*[LF]'\E*[CF]'\E*[RF]'
+.de OH
+.ds pg*\\$0 "\\$*
+..
+.als EH OH
+.als OF OH
+.als EF OH
+.aln PN % \" Lesk 1978 documents PN.
+.de PT
+.\" To compare the page number to 1, we need it in Arabic format.
+.ds pg*saved-page-number-format \\g%\"
+.af % 0
+.nr pg*page-number-in-decimal \\n%
+.af % \\*[pg*saved-page-number-format]
+.fam \\*[pg@titles-font-family]
+.ie \\n[pg*page-number-in-decimal]=1 .if \\n[pg*P1] .tl \\*[pg*OH]
+.el \{\
+. ie o .tl \\*[pg*OH]
+. el .tl \\*[pg*EH]
+.\}
+.rm pg*saved-page-number-format
+..
+.de BT
+.fam \\*[pg@titles-font-family]
+.ie o .tl \\*[pg*OF]
+.el .tl \\*[pg*EF]
+..
+.nr pg*P1 0
+.de P1
+.nr pg*P1 1
+..
+.wh -\n[FM]u pg@bottom
+.wh -\n[FM]u/2u pg*footer
+.nr MINGW 2n
+.nr pg@ncols 1
+.de @MC
+.if !'\\n(.z'' .@error-recover .MC while diversion open
+.br
+.ie \\n[pg@ncols]>1 .pg@super-eject
+.el \{\
+. \" flush out any floating keeps
+. while \\n[kp@tail]>\\n[kp@head] \{\
+. rs
+. bp
+. \}
+.\}
+.ie !\\n(.$ \{\
+. nr pg*gutw \\n[MINGW]
+. nr pg@colw \\n[LL]-\\n[pg*gutw]/2u
+. nr pg@ncols 2
+.\}
+.el \{\
+. nr pg@colw (n;\\$1)<?\\n[LL]
+. ie \\n[.$]<2 .nr pg*gutw \\n[MINGW]
+. el .nr pg*gutw (n;\\$2)
+. nr pg@ncols \\n[LL]-\\n[pg@colw]/(\\n[pg@colw]+\\n[pg*gutw])+1
+. ie \\n[pg@ncols]>1 \
+. nr pg*gutw \\n[LL]-(\\n[pg@ncols]*\\n[pg@colw])/(\\n[pg@ncols]-1)
+. el .nr pg*gutw 0
+.\}
+.DEVTAG ".mc \\n[pg@ncols] \\n[pg@colw] \\n[pg*gutw]"
+.nr pg*col-num 0
+.nr pg@fn-colw \\n[pg@colw]*\\*[FR]
+.par@reset
+.ns
+.mk pg*col-top
+..
+.de 2C
+.MC
+..
+.de 1C
+.MC \\n[LL]u
+..
+.de pg@top
+.\" invoked by '.wh 0' trap at the top of every page
+.\"
+.\" At short page lengths, footers may get truncated or recursion may
+.\" occur; ensure that the page length suffices to avoid these problems.
+.if (u;\\n[HM]+\\n[FM]+\n[.V]>=\\n[.p]) \{\
+. @error insufficient page length; aborting\"
+. pl \\n[nl]u
+. ab
+.\}
+.ch pg*footer -\\n[FM]u/2u
+.nr pg*col-num 0
+.nr pg@fn-bottom-margin 0
+.po \\n[PO]u
+.ev h
+.par@reset
+.sp (u;\\n[HM]/2)
+.PT
+.sp |\\n[HM]u
+.if d HD .HD
+.mk pg@header-bottom
+.ev
+.mk pg*col-top
+.pg*start-col
+..
+.de pg*start-col
+.\" Handle footnote overflow before floating keeps, because the keep
+.\" might contain an embedded footnote.
+.fn@top-hook
+.kp@top-hook
+.tbl@top-hook
+.ns
+..
+.de pg@cs-top
+.sp \\n[HM]u
+.\" move pg@bottom and pg*footer out of the way
+.ch pg@bottom \\n[.p]u*2u
+.ch pg*footer \\n[.p]u*2u
+.ns
+..
+.de pg@bottom
+.tbl@bottom-hook
+.if \\n[pg@fn-flag] .fn@bottom-hook
+.nr pg*col-num +1
+.ie \\n[pg*col-num]<\\n[pg@ncols] .pg*end-col
+.el .pg*end-page
+..
+.de pg*end-col
+'sp |\\n[pg*col-top]u
+.po (u;\\n[PO]+(\\n[pg@colw]+\\n[pg*gutw]*\\n[pg*col-num]))
+.\"po +(u;\\n[pg@colw]+\\n[pg*gutw])
+.pg*start-col
+..
+.de pg*end-page
+.po \\n[PO]u
+.\" Make sure we don't exit if there are still floats or footnotes
+.\" left-over.
+.ie \\n[kp@head]<\\n[kp@tail]:\\n[fn@have-overflow] \{\
+. \" Switching environments ensures that we don't get an unnecessary
+. \" blank line at the top of the page.
+. ev ne
+' bp
+. ev
+.\}
+.el \{\
+. \" If the text has ended and there are no more footnotes or
+. \" keeps, exit.
+. if \\n[pg@text-ended] .ex
+. if r pg*next-number \{\
+. pn \\n[pg*next-number]
+. rr pg*next-number
+. if d pg*next-format \{\
+. af % \\*[pg*next-format]
+. rm pg*next-format
+. \}
+. \}
+' bp
+.\}
+..
+.\" pg@begin number format
+.de pg@begin
+.ie \\n[.$]>0 \{\
+. nr pg*next-number (;\\$1)
+. ie \\n[.$]>1 .ds pg*next-format \\$2
+. el .rm pg*next-format
+.\}
+.el .rr pg*next-number
+.pg@super-eject
+..
+.\" print the footer line
+.de pg*footer
+.ev h
+.par@reset
+.BT
+.ev
+..
+.\" flush out any keeps or footnotes
+.de pg@super-eject
+.br
+.if !'\\n(.z'' \{\
+. ds @msg diversion open while ejecting page\"
+. as @msg " (last file seen: \\*[@last-file-seen])\"
+. @error-recover \\*[@msg]
+. rm @msg
+.\}
+.\" Make sure we stay in the end macro while there is still footnote
+.\" overflow left, or floating keeps.
+.while \\n[kp@tail]>\\n[kp@head]:\\n[pg@fn-flag] \{\
+. rs
+. bp
+.\}
+.bp
+..
+.nr pg@text-ended 0
+.de pg@end-text
+.br
+.nr pg@text-ended 1
+.pg@super-eject
+..
+.em pg@end-text
+.\" ***************************
+.\" ******** module fn ********
+.\" ***************************
+.\" Footnotes.
+.nr fn@sep-dist 8p
+.ev fn
+.\" Round it vertically
+.vs \n[fn@sep-dist]u
+.nr fn@sep-dist \n[.v]
+.ev
+.nr fn*text-num 0 1
+.nr fn*note-num 0 1
+.nr fn*open 0
+.\" Handle initialition tasks deferred until par module is set up.
+.de fn@init
+.ie t .als fn@mark-start par@sup-start
+.el .ds fn@mark-start [
+.ie t .als fn@mark-end par@sup-end
+.el .ds fn@mark-end ]
+.ds * \E*[fn@mark-start]\En+[fn*text-num]\E*[fn@mark-end]
+..
+.\" normal FS
+.\" FS-MARK is a user definable hook, which may be used to perform
+.\" any set-up actions, (e.g. planting an HREF link as the footnote
+.\" mark, in the document text); passed the same arguments as have
+.\" been passed to FS itself, unless redefined, it is a no-op.
+.de @FS
+.FS-MARK \\$@
+.ie \\n[.$] .fn*do-FS "\\$1" no
+.el \{\
+. ie \\n[fn*text-num]>\\n[fn*note-num] .fn*do-FS \\n+[fn*note-num]
+. el .fn*do-FS
+.\}
+..
+.\" Default no-op fallback for FS-MARK
+.de FS-MARK
+..
+.\" Second argument of 'no' means don't embellish the first argument.
+.de fn*do-FS
+.if \\n[fn*open] .@error-recover nested .FS
+.nr fn*open 1
+.if \\n[.u] \{\
+. \" Ensure that the first line of the footnote is on the same page
+. \" as the reference. I think this is minimal.
+. ev fn
+. nr fn*need 1v
+. ev
+. ie \\n[pg@fn-flag] .nr fn*need +\\n[fn:PD]
+. el .nr fn*need +\\n[fn@sep-dist]
+. ne \\n[fn*need]u+\\n[.V]u>?0
+.\}
+.ev fn
+.par@reset-env
+.fn*start-div
+.par@reset
+.fam \\*[fn@font-family]
+.ie \\n[.$] .FP \\$@
+.el .@LP
+..
+.de @FE
+.ie !\\n[fn*open] .@error .FE without .FS
+.el \{\
+. nr fn*open 0
+. br
+. ev
+. fn*end-div
+.\}
+..
+.nr fn@have-overflow 0
+.\" called at the top of each column
+.de fn@top-hook
+.nr fn*max-width 0
+.nr fn*page-bottom-pos 0-\\n[FM]-\\n[pg@fn-bottom-margin]
+.ch pg@bottom \\n[fn*page-bottom-pos]u
+.if \\n[fn@have-overflow] \{\
+. nr fn@have-overflow 0
+. fn*start-div
+. ev nf
+. fn@overflow-div
+. ev
+. fn*end-div
+.\}
+..
+.\" This is called at the bottom of the column if pg@fn-flag is set.
+.de fn@bottom-hook
+.nr pg@fn-flag 0
+.nr fn@have-overflow 0
+.nr fn@bottom-pos \\n[.p]-\\n[FM]-\\n[pg@fn-bottom-margin]+\\n[.v]
+.ev fn
+.nr fn@bottom-pos -\\n[.v]
+.ev
+.ie \\n[nl]+\\n[fn@sep-dist]+\n[.V]>\\n[fn@bottom-pos] \{\
+. rn fn@div fn@overflow-div
+. nr fn@have-overflow 1
+.\}
+.el \{\
+. if \\n[pg@ncols]>1 \
+. if \\n[fn*max-width]>\\n[pg@fn-colw] \
+. nr pg@fn-bottom-margin \\n[.p]-\\n[FM]-\\n[nl]+1v
+. wh \\n[fn@bottom-pos]u fn*catch-overflow
+. fn@print-sep
+. ev nf
+. fn@div
+. rm fn@div
+. ev
+. if '\\n(.z'fn@overflow-div' \{\
+. di
+. nr fn@have-overflow \\n[dn]>0
+. \}
+. ch fn*catch-overflow
+.\}
+..
+.de fn*catch-overflow
+.di fn@overflow-div
+..
+.nr fn*embed-count 0
+.de @div-end!fn@div
+.br
+.if '\\n[.ev]'fn' .ev
+.fn*end-div
+.nr fn*open 0
+..
+.als @div-end!fn*embed-div @div-end!fn@div
+.de fn*start-div
+.ie '\\n(.z'' \{\
+. da fn@div
+. if !\\n[pg@fn-flag] .ns
+.\}
+.el .di fn*embed-div
+..
+.de fn*end-div
+.ie '\\n(.z'fn@div' \{\
+. di
+. nr fn*page-bottom-pos -\\n[dn]
+. nr fn*max-width \\n[fn*max-width]>?\\n[dl]
+. if !\\n[pg@fn-flag] .nr fn*page-bottom-pos -\\n[fn@sep-dist]
+. nr pg@fn-flag 1
+. nr fn*page-bottom-pos \\n[nl]-\\n[.p]+\n[.V]>?\\n[fn*page-bottom-pos]
+. ch pg@bottom \\n[fn*page-bottom-pos]u
+.\}
+.el \{\
+. ie '\\n(.z'fn*embed-div' \{\
+. di
+. rn fn*embed-div fn*embed-div!\\n[fn*embed-count]
+\!. fn*embed-start \\n[fn*embed-count]
+. rs
+' sp (u;\\n[dn]+\\n[fn@sep-dist]+\\n[.V])
+\!. fn*embed-end
+. nr fn*embed-count +1
+. \}
+. el \{\
+. ev fn
+. @error-recover unclosed diversion within footnote
+. \}
+.\}
+..
+.de fn*embed-start
+.ie '\\n(.z'' \{\
+. fn*start-div
+. ev nf
+. fn*embed-div!\\$1
+. rm fn*embed-div!\\$1
+. ev
+. fn*end-div
+. di fn*null
+.\}
+.el \{\
+\!. fn*embed-start \\$1
+. rs
+.\}
+..
+.de fn*embed-end
+.ie '\\n(.z'fn*null' \{\
+. di
+. rm fn*null
+.\}
+.el \!.fn*embed-end
+..
+.\" It's important that fn@print-sep use up exactly fn@sep-dist vertical
+.\" space.
+.de fn@print-sep
+.ev fn
+.in 0
+.vs \\n[fn@sep-dist]u
+\D'l 1i 0'
+.br
+.ev
+..
+.\" ***************************
+.\" ******** module kp ********
+.\" ***************************
+.\" Keeps.
+.de KS
+.br
+.di kp@div
+..
+.de KF
+.if !'\\n(.z'' .@error-recover .KF while diversion open
+.di kp@fdiv
+.ev k
+.par@reset-env
+.par@reset
+..
+.de KE
+.ie '\\n(.z'kp@div' .kp*end
+.el \{\
+. ie '\\n(.z'kp@fdiv' .kp*fend
+. el .@error .KE without .KS or .KF
+.\}
+..
+.de @div-end!kp@div
+.kp*end
+..
+.de @div-end!kp@fdiv
+.kp*fend
+..
+.de kp*need
+.ie '\\n(.z'' .ds@need \\$1
+.el \!.kp*need \\$1
+..
+.\" end non-floating keep
+.de kp*end
+.br
+.di
+.kp*need \\n[dn]
+.ev nf
+.kp@div
+.ev
+.rm kp@div
+..
+.\" Floating keeps.
+.nr kp@head 0
+.nr kp@tail 0
+.\" end floating keep
+.de kp*fend
+.br
+.ev
+.di
+.ie \\n[.t]-(\\n[.k]>0*1v)>\\n[dn] \{\
+. br
+. ev nf
+. kp@fdiv
+. rm kp@fdiv
+. ev
+.\}
+.el \{\
+. rn kp@fdiv kp@div!\\n[kp@tail]
+. nr kp*ht!\\n[kp@tail] 0\\n[dn]
+. nr kp@tail +1
+.\}
+..
+.\" top of page processing for KF
+.nr kp*doing-top 0
+.de kp@top-hook
+.if !\\n[kp*doing-top] \{\
+. nr kp*doing-top 1
+. kp*do-top
+. nr kp*doing-top 0
+.\}
+..
+.de kp*do-top
+.\" If the first keep won't fit, only force it out if we haven't had a
+.\" footnote and we're at the top of the page.
+.nr kp*force \\n[pg@fn-flag]=0&(\\n[nl]<=\\n[pg@header-bottom])
+.nr kp*fits 1
+.while \\n[kp@tail]>\\n[kp@head]&\\n[kp*fits] \{\
+. ie \\n[.t]>\\n[kp*ht!\\n[kp@head]]:\\n[kp*force] \{\
+. nr kp*force 0
+. \" It's important to advance kp@head before bringing
+. \" back the keep, so that if the last line of the
+. \" last keep springs the bottom of page trap, a new
+. \" page will not be started unnecessarily.
+. rn kp@div!\\n[kp@head] kp*temp
+. nr kp@head +1
+. ev nf
+. kp*temp
+. ev
+. rm kp*temp
+. \}
+. el .nr kp*fits 0
+.\}
+..
+.\" ***************************
+.\" ******** module ds ********
+.\" ***************************
+.\" Displays and non-floating keeps.
+.de DE
+.ds*end!\\n[\\n[.ev]:ds-type]
+.nr \\n[.ev]:ds-type 0
+.ns
+..
+.de ds@auto-end
+.if \\n[\\n[.ev]:ds-type] \{\
+. @error automatically terminating display
+. DE
+.\}
+..
+.de @div-end!ds*div
+.ie \\n[\\n[.ev]:ds-type] .DE
+.el .ds*end!2
+..
+.de ds*end!0
+.@error .DE without .DS, .ID, .CD, .LD, .RD, or .BD
+..
+.de LD
+.br
+.nr \\n[.ev]:ds-type 1
+.par@reset
+.nf
+.sp \\n[DD]u
+..
+.de ID
+.LD
+.ie \\n[.$] .in +(n;\\$1)
+.el .in +\\n[DI]u
+..
+.de CD
+.LD
+.ce 9999
+..
+.de RD
+.LD
+.rj 9999
+..
+.de ds*common-end
+.par@reset
+.sp \\n[DD]u
+..
+.als ds*end!1 ds*common-end
+.de BD
+.LD
+.nr \\n[.ev]:ds-type 2
+.di ds*div
+..
+.de ds*end!2
+.br
+.ie '\\n(.z'ds*div' \{\
+. di
+. nf
+. in (u;\\n[.l]-\\n[dl]/2>?0)
+. ds*div
+. rm ds*div
+. ds*common-end
+.\}
+.el .@error-recover mismatched .DE
+..
+.de DS
+.if '\\n(.z'ds*div' .@error-recover cannot begin display within display
+.nr ds*badarg 0
+.di ds*div
+.ie '\\$1'B' \{\
+. LD
+. nr \\n[.ev]:ds-type 4
+.\}
+.el \{\
+. ie '\\$1'L' .LD
+. el \{\
+. ie '\\$1'C' .CD
+. el \{\
+. ie '\\$1'R' .RD
+. el \{\
+. ie '\\$1'I' .ID \\$2
+. el \{\
+. ie '\\$1'' .ID
+. el .nr ds*badarg 1
+. \}
+. \}
+. \}
+. \}
+. ie \\n[ds*badarg] \{\
+. ds ds*msg unrecognized argument '\\$1' to .\\$0;\"
+. as ds*msg " did you mean '.\\$0 I \\$1'?\"
+. @error \\*[ds*msg]
+. rm ds*msg
+. di
+. \}
+. el .nr \\n[.ev]:ds-type 3
+.\}
+.rr ds*badarg
+..
+.de ds@need
+.if '\\n(.z'' \{\
+. while \\n[.t]<=(\\$1)&(\\n[nl]>\\n[pg@header-bottom]) \{\
+. rs
+' sp \\n[.t]u
+. \}
+.\}
+..
+.de ds*end!3
+.br
+.ie '\\n(.z'ds*div' \{\
+. di
+. ds@need \\n[dn]
+. ev nf
+. ds*div
+. ev
+. rm ds*div
+. ds*common-end
+.\}
+.el .@error-recover mismatched .DE
+..
+.de ds*end!4
+.ie '\\n(.z'ds*div' \{\
+. br
+. di
+. nf
+. in (u;\\n[.l]-\\n[dl]/2>?0)
+. ds@need \\n[dn]
+. ds*div
+. rm ds*div
+. ds*common-end
+.\}
+.el .@error-recover mismatched .DE
+..
+.\" ****************************
+.\" ******** module par ********
+.\" ****************************
+.\" Paragraph-level formatting.
+.\" Load time initialization.
+.de par@load-init
+.\" PS and VS might have been set on the command line
+.if !rPS .nr PS 10
+.if !rLL .nr LL 6.5i
+.ll \\n[LL]u
+.\" don't set LT so that it can be defaulted from LL
+.ie rLT .lt \\n[LT]u
+.el .lt \\n[LL]u
+.ie (\\n[PS] >= 1000) \
+. ps (\\n[PS]z / 1000u)
+.el \
+. ps \\n[PS]
+.\" don't set VS so that it can be defaulted from PS
+.ie rVS \{\
+. ie (\\n[VS] >= 1000) \
+. par*vs "(\\n[VS]p / 1000u)"
+. el \
+. par*vs \\n[VS]
+.\}
+.el \{\
+. ie (\\n[PS] >= 1000) \
+. par*vs "((\\n[PS]p / 1000u) + 2p)"
+. el \
+. par*vs "(\\n[PS] + 2)"
+.\}
+.if dFAM .fam \\*[FAM]
+.if !rHY .nr HY 6
+.hy \\n[HY]
+.TA
+.CHECK-FOOTER-AND-KEEP
+..
+.de par*vs
+.\" If it's too big to be in points, treat it as units.
+.ie (p;\\$1)>=40p .vs (u;\\$1)
+.el .vs (p;\\$1)
+..
+.de par@ab-indent
+.nr 0:li (u;\\n[LL]/12)
+.nr 0:ri \\n[0:li]
+..
+.de par*env-init
+.aln \\n[.ev]:PS PS
+.aln \\n[.ev]:VS VS
+.aln \\n[.ev]:LL LL
+.aln \\n[.ev]:MCLL LL
+.aln \\n[.ev]:LT LT
+.aln \\n[.ev]:MCLT LT
+.aln \\n[.ev]:PI PI
+.aln \\n[.ev]:PD PD
+.ad \\n[par*adj]
+.par@reset-env
+..
+.\" happens when the first page begins
+.de par@init
+.if !rLT .nr LT \\n[LL]
+.if !rFL .nr FL \\n[LL]*\\*[FR]
+.if !rVS \{\
+. ie (\\n[PS] >= 1000) \
+. nr VS (\\n[PS] + 2000)
+. el \
+. nr VS (\\n[PS] + 2)
+.\}
+.if !rDI .nr DI .5i
+.if !rFPS \{\
+. ie (\\n[PS] >= 1000) \
+. nr FPS (\\n[PS] - 2000)
+. el \
+. nr FPS (\\n[PS] - 2)
+.\}
+.if !rFVS \{\
+. ie (\\n[FPS] >= 1000) \
+. nr FVS (\\n[FPS] + 2000)
+. el \
+. nr FVS (\\n[FPS] + 2)
+.\}
+.\" don't change environment 0
+.ev h
+.ie (\\n[PS] >= 1000) \
+. ps (\\n[PS]z / 1000u)
+.el \
+. ps \\n[PS]
+.if !rQI .nr QI 5n
+.if !rPI .nr PI 5n
+.ie (\\n[VS] >= 1000) \
+. par*vs "(\\n[VS]p / 1000u)"
+.el \
+. par*vs \\n[VS]
+.if !rPD .nr PD .3v>?\n(.V
+.if !rDD .nr DD .5v>?\n(.V
+.if !rFI .nr FI 2n
+.if !rFPD .nr FPD \\n[PD]/2
+.ev
+.if !dFAM .ds FAM \\n[.fam]
+.ds pg@titles-font-family \\*[FAM]
+.ds fn@font-family \\*[FAM]
+.nr par*adj \\n[.j]
+.par*env-init
+.ev h
+.par*env-init
+.ev
+.ev fn
+.par*env-init
+.ev
+.ev k
+.par*env-init
+.ev
+.aln 0:MCLL pg@colw
+.aln 0:MCLT pg@colw
+.aln k:MCLL pg@colw
+.aln k:MCLT pg@colw
+.aln fn:PS FPS
+.aln fn:VS FVS
+.aln fn:LL FL
+.aln fn:LT FL
+.aln fn:PI FI
+.aln fn:PD FPD
+.aln fn:MCLL pg@fn-colw
+.aln fn:MCLT pg@fn-colw
+..
+.de par@reset-env
+.nr \\n[.ev]:il 0
+.nr \\n[.ev]:li 0
+.nr \\n[.ev]:ri 0
+.nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
+.nr \\n[.ev]:pli 0
+.nr \\n[.ev]:pri 0
+.nr \\n[.ev]:ds-type 0
+..
+.\" par@reset
+.de par@reset
+.br
+.if \\n[s@devtag-needs-end-of-title] .DEVTAG-EO-TL
+.nr s@devtag-needs-end-of-title 0
+.if \\n[s@devtag-needs-end-of-heading] .DEVTAG-EO-H
+.nr s@devtag-needs-end-of-heading 0
+.ce 0
+.rj 0
+.ul 0
+.fi
+.ft 1
+.ie '\\n[.ev]'fn' .fam \\*[fn@font-family]
+.el .fam \\*[FAM]
+.ie (\\n[\\n[.ev]:PS] >= 1000) \
+. ps (\\n[\\n[.ev]:PS]z / 1000u)
+.el \
+. ps \\n[\\n[.ev]:PS]
+.ie (\\n[\\n[.ev]:VS] >= 1000) \
+. par*vs "(\\n[\\n[.ev]:VS]p / 1000u)"
+.el \
+. par*vs \\n[\\n[.ev]:VS]
+.ls 1
+.if !'\\$1'' .nr \\n[.ev]:pli (n;\\$1)
+.if !'\\$2'' .nr \\n[.ev]:pri (n;\\$2)
+.ie \\n[pg@ncols]>1 \{\
+. ll (u;\\n[\\n[.ev]:MCLL]-\\n[\\n[.ev]:ri]-\\n[\\n[.ev]:pri])
+. lt \\n[\\n[.ev]:MCLT]u
+.\}
+.el \{\
+. ll (u;\\n[\\n[.ev]:LL]-\\n[\\n[.ev]:ri]-\\n[\\n[.ev]:pri])
+. lt \\n[\\n[.ev]:LT]u
+.\}
+.in (u;\\n[\\n[.ev]:li]+\\n[\\n[.ev]:pli])
+.TA
+.hy \\n[HY]
+..
+.\" This can be redefined by the user.
+.de TA
+.ta T 5n
+..
+.\" \n[PORPHANS] sets number of initial lines of any paragraph,
+.\" which must be kept together, without any included page break.
+.\" Initialise to reproduce original behaviour; user may adjust it.
+.if !rPORPHANS .nr PORPHANS 1
+.
+.de par*start
+.ds@auto-end
+.par@reset \\$1 \\$2
+.sp \\n[\\n[.ev]:PD]u
+.ne \\n[PORPHANS]v+\\n(.Vu
+..
+.de par@finish
+.nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
+.nr \\n[.ev]:pli 0
+.nr \\n[.ev]:pri 0
+.par@reset 0 0
+..
+.als @RT par@finish
+.\" normal LP
+.de @LP
+.par*start 0 0
+.nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
+..
+.de @PP
+.par*start 0 0
+.nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
+.if !'\*(.T'html' .ti +\\n[\\n[.ev]:ai]u
+..
+.de @QP
+.nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
+.par*start \\n[QI]u \\n[QI]u
+..
+.de @XP
+.par*start \\n[\\n[.ev]:PI]u 0
+.ti -\\n[\\n[.ev]:PI]u
+..
+.de @IP
+.ie \\n[.$]>1 \{\
+.par*start \\$2 0
+.nr \\n[.ev]:ai \\n[\\n[.ev]:pli]
+.\}
+.el .par*start \\n[\\n[.ev]:ai]u 0
+.if !'\\$1'' \{\
+. \" Divert the label so as to freeze any spaces.
+. di par*label
+. par*push-tag-env
+\&\\$1
+. par*pop-tag-env
+. di
+. chop par*label
+. ti -\\n[\\n[.ev]:ai]u
+. ie \\n[dl]+1n<=\\n[\\n[.ev]:ai] \{\
+. DEVTAG-COL 1
+\\*[par*label]\h'|\\n[\\n[.ev]:ai]u'\c
+. DEVTAG-COL 2
+. \}
+. el \{\
+. DEVTAG-COL 1
+\\*[par*label]
+. DEVTAG-COL-NEXT 2
+. br
+. \}
+. rm par*label
+.\}
+..
+.\" We don't want margin characters to be attached when we divert
+.\" the tag. Since there's no way to save and restore the current
+.\" margin character, we have to switch to a new environment, taking
+.\" what we need of the old environment with us.
+.de par*push-tag-env
+.nr par*saved-font \\n[.f]
+.nr par*saved-size \\n[.s]z
+.nr par*saved-ss \\n[.ss]
+.nr par*saved-sss \\n[.sss]
+.ds par*saved-fam \\n[.fam]
+.ev par
+.nf
+.TA
+.ft \\n[par*saved-font]
+.ps \\n[par*saved-size]u
+.ss \\n[par*saved-ss] \\n[par*saved-sss]
+.fam \\*[par*saved-fam]
+..
+.de par*pop-tag-env
+.ev
+..
+.de @RS
+.br
+.nr \\n[.ev]:li!\\n[\\n[.ev]:il] \\n[\\n[.ev]:li]
+.nr \\n[.ev]:ri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ri]
+.nr \\n[.ev]:ai!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ai]
+.nr \\n[.ev]:pli!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pli]
+.nr \\n[.ev]:pri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pri]
+.nr \\n[.ev]:il +1
+.nr \\n[.ev]:li +\\n[\\n[.ev]:ai]
+.nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
+.par@reset
+..
+.de @RE
+.br
+.ie \\n[\\n[.ev]:il] \{\
+. nr \\n[.ev]:il -1
+. nr \\n[.ev]:ai \\n[\\n[.ev]:ai!\\n[\\n[.ev]:il]]
+. nr \\n[.ev]:li \\n[\\n[.ev]:li!\\n[\\n[.ev]:il]]
+. nr \\n[.ev]:ri \\n[\\n[.ev]:ri!\\n[\\n[.ev]:il]]
+. nr \\n[.ev]:pli \\n[\\n[.ev]:pli!\\n[\\n[.ev]:il]]
+. nr \\n[.ev]:pri \\n[\\n[.ev]:pri!\\n[\\n[.ev]:il]]
+.\}
+.el .@error unbalanced .\\$0
+.ie '\\$0'QE' .par*start 0 0
+.el .par@reset
+..
+.de @QS
+.br
+.nr \\n[.ev]:li!\\n[\\n[.ev]:il] \\n[\\n[.ev]:li]
+.nr \\n[.ev]:ri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ri]
+.nr \\n[.ev]:ai!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ai]
+.nr \\n[.ev]:pli!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pli]
+.nr \\n[.ev]:pri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pri]
+.nr \\n[.ev]:il +1
+.nr \\n[.ev]:li +\\n[QI]
+.nr \\n[.ev]:ri +\\n[QI]
+.nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
+.par*start 0 0
+..
+.als @QE @RE
+.\" start boxed text
+.de B1
+.br
+.HTML-IMAGE
+.di par*box-div
+.nr \\n[.ev]:li +1n
+.nr \\n[.ev]:ri +1n
+.nr par*box-in \\n[.in]
+.\" remember what 1n is, just in case the point size changes
+.nr par*box-n 1n
+.in +1n
+.ll -1n
+.lt -1n
+.ti \\n[par*box-in]u+1n
+..
+.de @div-end!par*box-div
+.B2
+..
+.\" end boxed text
+.\" Postpone the drawing of the box until we're in the top-level
+.\" diversion, in case there's a footnote inside the box.
+.de B2
+.ie '\\n(.z'par*box-div' \{\
+. br
+. if \n[.V]>.25m .sp
+. di
+. if \n[.V]>.25m .sp
+. ds@need \\n[dn]
+. par*box-mark-top
+. ev nf
+. par*box-div
+. ev
+. nr \\n[.ev]:ri -\\n[par*box-n]
+. nr \\n[.ev]:li -\\n[par*box-n]
+. in -\\n[par*box-n]u
+. ll +\\n[par*box-n]u
+. lt +\\n[par*box-n]u
+. par*box-draw \\n[.i]u \\n[.l]u-(\\n[.H]u==1n*1n)
+.\}
+.el .@error .B2 without .B1
+.HTML-IMAGE-END
+..
+.de par*box-mark-top
+.ie '\\n[.z]'' \{\
+. rs
+. mk par*box-top
+.\}
+.el \!.par*box-mark-top
+..
+.de par*box-draw
+.ie '\\n[.z]'' \{\
+. nr par*box-in \\n[.i]
+. nr par*box-ll \\n[.l]
+. nr par*box-vpt \\n[.vpt]
+. nr par*box-ad \\n[.j]
+. ad l
+. vpt 0
+. in \\$1
+. ll \\$2
+\v'-1v+.25m'\
+\D'l (u;\\n[.l]-\\n[.i]) 0'\
+\D'l 0 |\\n[par*box-top]u'\
+\D'l -(u;\\n[.l]-\\n[.i]) 0'\
+\D'l 0 -|\\n[par*box-top]u'
+. br
+. sp -1
+. in \\n[par*box-in]u
+. ll \\n[par*box-ll]u
+. vpt \\n[par*box-vpt]
+. ad \\n[par*box-ad]
+.\}
+.el \!.par*box-draw \\$1 \\$2
+..
+.\" \n[HORPHANS] sets how many lines of the following paragraph must be
+.\" kept together, with a preceding section header. Initialise it,
+.\" to reproduce original behaviour; user may change it.
+.if !rHORPHANS .nr HORPHANS 1
+.
+.\" \n[GROWPS] and \n[PSINCR] cause auto-increment of header point size.
+.\" Initialise them, so they have no effect, unless explicitly set by
+.\" the user.
+.if !rGROWPS .nr GROWPS 0
+.if !rPSINCR .nr PSINCR 1p
+.
+.de SH-NO-TAG
+.par@finish
+.\" Keep the heading and the first few lines of the next paragraph
+.\" together. (\n[HORPHANS] defines "first few" -- default = 1; user
+.\" may redefine it).
+.nr sh*minvs \\n[HORPHANS]v
+.if \\n[sh*psincr]<0 .nr sh*psincr 0
+.ie \\n(VS<1000 .par*vs \\n(VSp+\\n[sh*psincr]u
+.el .par*vs \\n(VSp/1000u+\\n[sh*psincr]u
+.ne 2v+\\n[sh*minvs]u+\\n[\\n[.ev]:PD]u+\\n(.Vu
+.\" Adjust point size for heading text, as specified by \n[GROWPS] and
+.\" \n[PSINCR].
+.ie \\n(PS<1000 .ps \\n(PS+\\n[sh*psincr]u
+.el .ps \\n(PSz/1000u+\\n[sh*psincr]u
+.sp 1
+.ft B
+..
+.de @SH
+.\" Standard ms implementation does not expect an argument,
+.\" but allow ".SH n" to make heading point size match ".NH n",
+.\" for same "n", when \n[GROWPS] and \n[PSINCR] are set.
+. nr sh*psincr 0
+. if 0\\$1>0 .nr sh*psincr (\\n[GROWPS]-0\\$1)*\\n[PSINCR]
+. SH-NO-TAG
+. DEVTAG-SH 1
+. if '\*(.T'html' .nr s@devtag-needs-end-of-heading 1
+..
+.\" TL, AU, and AI are aliased to these in cov*ab-init.
+.de par@TL
+.par@finish
+.sp 1
+.ft B
+.ps +2
+.vs +3p
+.ce 9999
+.DEVTAG-TL
+.nr s@devtag-needs-end-of-title 1
+..
+.de par@AU
+.par@finish
+.sp 1
+.ft I
+.ce 9999
+..
+.de par@AI
+.par@finish
+.sp .5
+.ce 9999
+..
+.\" In paragraph macros.
+.de NL
+.if \En[.$] .@warning arguments to .NL ignored
+.ie (\\n[\\n[.ev]:PS] >= 1000) \
+. ps (\\n[\\n[.ev]:PS]z / 1000u)
+.el \
+. ps \\n[\\n[.ev]:PS]
+..
+.de SM
+.if \En[.$] .@warning arguments to .SM ignored
+.ps -2
+..
+.de LG
+.if \En[.$] .@warning arguments to .LG ignored
+.ps +2
+..
+.\" par*define-font-macro macro font apply-italic-corrections
+.de par*define-font-macro
+.de \\$1
+.ds par*lic \" empty
+.ds par*ic \" empty
+.if \\n[.$]>2 \{\
+. as par*lic \,\"
+. as par*ic \/\"
+.\}
+.if \En[.$]>3 .@warning excess arguments to .\\$1 ignored
+.ie \En[.$] \{\
+. nr par*prev-font \En[.f]
+\&\E$3\E*[par*lic]\f[\\$2]\E$1\f[\En[par*prev-font]]\E*[par*ic]\E$2
+.\}
+.el .ft \\$2
+\\..
+..
+.par*define-font-macro R R
+.par*define-font-macro B B
+.par*define-font-macro I I yes
+.par*define-font-macro BI BI yes
+.ie n .par*define-font-macro CW R
+.el .par*define-font-macro CW CR
+.\" underline a word
+.de UL
+.if \En[.$]>2 .@warning excess arguments to .UL ignored
+. ie t .do nop \Z'\\$1'\v'.25m'\D'l \w'\\$1'u 0'\v'-.25m'\\$2
+. el \(ul\\$1\(ul\\$2
+..
+.\" box a word
+.de BX
+.if \En[.$]>1 .@warning excess arguments to .BX ignored
+.nr par*bxw \w'\\$1'
+.ie t \{\
+.nr par*bxw +.4m
+\Z'\v'.25m'\
+\D'l 0 -1m'\D'l \\n[par*bxw]u 0'\D'l 0 1m'\D'l -\\n[par*bxw]u 0''\
+\Z'\h'.2m'\\$1'\h'\\n[par*bxw]u'
+.\}
+.el \m[black]\M[white]\Z'\\$1'\h'\\n[par*bxw]u'\m[]\M[]
+..
+.\" superscript
+.ds par@sup-start \v'-.9m\s'\En[.s]*7u/10u'+.7m'
+.als { par@sup-start
+.ds par@sup-end \v'-.7m\s0+.9m'
+.als } par@sup-end
+.\" subscript
+.ds par@sub-start \v'+.3m\s'\En[.s]*7u/10u'-.1m'
+.als < par@sub-start
+.ds par@sub-end \v'+.1m\s0-.3m'
+.als > par@sub-end
+.\" footnote paragraphs
+.fn@init
+.\" FR is the ratio of footnote (horizontal) length to the line length
+.ds FR 11/12
+.\" FF is the footnote format
+.nr FF 0
+.\" This can be redefined. It gets a second argument of 'no' if the
+.\" first argument was supplied by the user, rather than automatically.
+.de FP
+.br
+.if !d par*fp!\\n[FF] \{\
+. @error unknown footnote format '\\n[FF]'
+. nr FF 0
+.\}
+.ie '\\$2'no' .par*fp!\\n[FF]-no "\\$1"
+.el .par*fp!\\n[FF] "\\$1"
+..
+.de par*fp!0
+.@PP
+\&\\*[fn@mark-start]\\$1\\*[fn@mark-end]\ \c
+..
+.de par*fp!0-no
+.@PP
+\&\\$1\ \c
+..
+.de par*fp!1
+.@PP
+\&\\$1.\ \c
+..
+.de par*fp!1-no
+.@PP
+\&\\$1\ \c
+..
+.de par*fp!2
+.@LP
+\&\\$1.\ \c
+..
+.de par*fp!2-no
+.@LP
+\&\\$1\ \c
+..
+.de par*fp!3
+.@IP "\\$1." (u;\\n[\\n[.ev]:PI]*2)
+..
+.de par*fp!3-no
+.@IP "\\$1" (u;\\n[\\n[.ev]:PI]*2)
+..
+.\" ***************************
+.\" ******** module nh ********
+.\" ***************************
+.\" Numbered headings.
+.\" nh*hl is the level of the last heading
+.nr nh*hl 0
+.\" SN-DOT and SN-NO-DOT represent the section number of
+.\" the current heading, with and without a terminating dot.
+.ds SN-DOT
+.ds SN-NO-DOT
+.\" SN-STYLE sets the statement numbering style used in headings
+.\" (either SN-DOT or SN-NO-DOT); for backward compatibility with
+.\" earlier ms versions, the default is SN-DOT
+.als SN-STYLE SN-DOT
+.\" Also for backward compatibility, let SN represent SN-DOT.
+.als SN SN-DOT
+.\" numbered heading
+.de @NH
+.ie '\\$1'S' \{\
+. shift
+. nr nh*hl 0
+. while \\n[.$] \{\
+. nr nh*hl +1
+. nr H\\n[nh*hl] 0\\$1
+. shift
+. \}
+. if !\\n[nh*hl] \{\
+. nr H1 1
+. nr nh*hl 1
+. @error missing arguments to .NH S
+. \}
+.\}
+.el \{\
+. nr nh*ohl \\n[nh*hl]
+. ie \\n[.$] \{\
+. nr nh*hl 0\\$1
+. ie \\n[nh*hl]<=0 \{\
+. nr nh*ohl 0
+. nr nh*hl 1
+. \}
+. el \{\
+. if \\n[nh*hl]-\\n[nh*ohl]>1 \{\
+. ds nh*msg .NH \\n[nh*ohl] followed by\"
+. as nh*msg " .NH \\n[nh*hl]\"
+. @warning \\*[nh*msg]
+. rm nh*msg
+. \}
+. \}
+. \}
+. el .nr nh*hl 1
+. while \\n[nh*hl]>\\n[nh*ohl] \{\
+. nr nh*ohl +1
+. nr H\\n[nh*ohl] 0
+. \}
+. nr H\\n[nh*hl] +1
+.\}
+.ds SN-NO-DOT \\n(H1
+.nr nh*i 1
+.while \\n[nh*i]<\\n[nh*hl] \{\
+. nr nh*i +1
+. as SN-NO-DOT .\\n[H\\n[nh*i]]
+.\}
+.ds SN-DOT \\*[SN-NO-DOT].
+.nr sh*psincr (\\n[GROWPS]-\\n[nh*hl])*\\n[PSINCR]
+.SH-NO-TAG
+.DEVTAG-NH "\\$1"
+.if '\*(.T'html' .nr s@devtag-needs-end-of-heading 1
+\\*[SN-STYLE]
+..
+.\" ****************************
+.\" ******** module toc ********
+.\" ****************************
+.\" Table of contents generation.
+.de @XS
+.da toc*div
+.ev h
+.ie \\n[.$] .XA "\\$1"
+.el .XA
+..
+.de @div-end!toc*div
+.XE
+..
+.de XA
+.ie '\\n(.z'toc*div' \{\
+. if d toc*num .toc*end-entry
+. ie \\n[.$] \{\
+. ie '\\$1'no' .ds toc*num \" empty
+. el .ds toc*num "\\$1
+. \}
+. el .ds toc*num \\n[%]\"
+. br
+. par@reset
+. na
+. in (n;0\\$2)
+.\}
+.el .@error .XA without .XS
+..
+.de XE
+.ie '\\n(.z'toc*div' \{\
+. if d toc*num .toc*end-entry
+. ev
+. di
+.\}
+.el .@error .XE without .XS
+..
+.\" Rudimentary integration of TOC generation with SH and NH;
+.\" (called by XH and XN respectively, to capture heading text
+.\" for reuse as TOC entry); may be redefined, to achieve more
+.\" sophisticated TOC layout effects.
+.\"
+.\" No-op initializers are called by XH and XN respectively,
+.\" before XH-UPDATE-TOC is called; if XH-UPDATE-TOC has been
+.\" redefined, then it may also be necessary to redefine either,
+.\" or both of these, to perform any initialization specific
+.\" to use after SH and NH respectively.
+.de XH-INIT de
+.de XN-INIT
+..
+.de XH-UPDATE-TOC
+.\" .XH-UPDATE-TOC <outline-level> <text>
+.XS
+.in (\\$1u - 1u * 2n)
+.shift
+\&\\$*
+.XE
+..
+.\" Rudimentary integration hook, to be called (nominally)
+.\" after SH, but acceptable in any body-text context
+.de XH de
+.\" .XH <outline-level> <text>
+.rn XH-REPLACEMENT XH
+.XH \\$@
+.de XH-REPLACEMENT
+.XH-INIT
+.XH-UPDATE-TOC \\$@
+.shift
+\&\\$*
+..
+.\" Rudimentary integration hook, to be called after NH
+.de XN de
+.\" .XN <text>
+.ie \\n[nh*hl] .toc*xn-init \\$@
+.el \{\
+. @error .XN is not allowed before .NH
+. nop \&\\$*
+.\}
+.de toc*xn-init de
+.rn XN-REPLACEMENT XN
+.XN \\$@
+.rm \\$0
+.de XN-REPLACEMENT
+.XN-INIT
+.XH-UPDATE-TOC \\n[nh*hl] \\$@
+\&\\$*
+..
+.de toc*end-entry
+.if !'\\*[toc*num]'' \\a\\t\\*[toc*num]
+.br
+.rm toc*num
+..
+.de PX
+.1C
+.if !'\\$1'no' \{\
+. ce 1
+. ie (\\n[PS] >= 1000) \
+. ps ((\\n[PS]z / 1000u) + 2z)
+. el \
+. ps \\n[PS]+2
+. ft B
+\\*[TOC]
+. ft
+. ps
+.\}
+.nf
+.if !r TC-MARGIN .nr TC-MARGIN \w'000'
+.if !c \[TC-LEADER] .char \[TC-LEADER] .\h'1m'
+.ta (u;\\n[.l]-\\n[.i]-\\n[TC-MARGIN]) (u;\\n[.l]-\\n[.i])R
+.lc \[TC-LEADER]
+.sp 2
+.toc*div
+.par@reset
+..
+.\" print the table of contents on page i
+.de TC
+.P1
+.pg@begin 1 i
+.PX \\$1
+..
+.\" ****************************
+.\" ******** module eqn ********
+.\" ****************************
+.\" Eqn support.
+.de EQ
+..
+.de EN
+..
+.de @EQ
+.if \\n[tbl@within-table] \
+. @error .EQ is not allowed within a .TS/.TE table
+.br
+.ds eqn*num "\\$2
+.ie '\\$1'L' .nr eqn*type 0
+.el \{\
+. ie '\\$1'I' .nr eqn*type 1
+. el \{\
+. nr eqn*type 2
+. if !'\\$1'C' .ds eqn*num "\\$1
+. \}
+.\}
+.di eqn*div
+.in 0
+.if '\*(.T'html' \{\
+. nr eqn*ll \\n[.l]
+. ll 1000n
+.\}
+.if \\n[eqn*type]=0 .EQN-HTML-IMAGE-LEFT
+.if \\n[eqn*type]=1 \{\
+. if '\*(.T'html' .RS
+.EQN-HTML-IMAGE-INLINE
+.\}
+.if \\n[eqn*type]=2 .EQN-HTML-IMAGE
+.nf
+..
+.de @div-end!eqn*div
+.@EN
+..
+.\" Note that geqn mark and lineup work correctly in centered equations.
+.de @EN
+.ie !'\\n(.z'eqn*div' .@error-recover mismatched .EN
+.el \{\
+. br
+. di
+. nr eqn*have-num 0
+. if !'\\*[eqn*num]'' .nr eqn*have-num 1
+. ie \\n[dl]:\\n[eqn*have-num] \{\
+. sp \\n[DD]u
+. ns
+. par@reset
+. ds eqn*tabs \\n[.tabs]
+. nf
+. ie \\n[dl] \{\
+.\" XXX: This really should not be necessary and
+.\" indicates that there is extra space creeping
+.\" into an equation when ps4html is enabled.
+. ie r ps4html .ds@need \\n[dn]u-1v+\n[.V]u+1i
+. el .ds@need \\n[dn]u-1v+\n[.V]u
+. chop eqn*div
+. ie \\n[eqn*type]=0 \{\
+. ta (u;\\n[.l]-\\n[.i])R
+\\*[eqn*div]\t\\*[eqn*num]
+. \}
+. el \{\
+. ie \\n[eqn*type]=1 .ta \\n[DI]u \
+(u;\\n[.l]-\\n[.i])R
+. el .ta (u;\\n[.l]-\\n[.i]/2)C \
+(u;\\n[.l]-\\n[.i])R
+\t\\*[eqn*div]\t\\*[eqn*num]
+. \}
+. \}
+. el \{\
+. ta (u;\\n[.l]-\\n[.i])R
+\t\\*[eqn*num]
+. \}
+.\". if !'\*(.T'html' .sp \\n[DD]u
+. sp \\n[DD]u
+. ns
+. ta \\*[eqn*tabs]
+. \}
+. el \{\
+.\" must terminate empty equations in html and ps4html as they contain
+.\" the EQN-HTML-IMAGE-END suppression nodes
+. if \\n[dl] .chop eqn*div
+. if '\*(.T'html' \\*[eqn*div]
+. if r ps4html \\*[eqn*div]
+. \}
+. if !'\*(.T'html' .fi
+. if \\n[eqn*type]=0 .EQN-HTML-IMAGE-END
+. if \\n[eqn*type]=1 \{\
+. EQN-HTML-IMAGE-END
+. if '\*(.T'html' .RE
+. \}
+. if \\n[eqn*type]=2 .EQN-HTML-IMAGE-END
+. if '\*(.T'html' \
+. ll \\n[eqn*ll]u
+.\}
+..
+.
+.\" ****************************
+.\" ******** module tbl ********
+.\" ****************************
+.\" Tbl support.
+.nr tbl@within-table 0
+.nr tbl*have-header 0
+.\" This gets called if TS occurs before the first paragraph.
+.de TS
+.LP
+.\" cov*ab-init, called by LP, aliases TS to @TS.
+\\*[TS]\\
+..
+.de @TS
+.nr tbl@within-table 1
+.sp \\n[DD]u
+.if '\\$1'H' \{\
+. ds tbl*stem .TS H table inside\"
+. ie '\\n[.z]'kp@div' .@warning \\*[tbl*stem] .KS/.KE keep
+. el .if '\\n[.z]'kp@fdiv' \
+. @warning \\*[tbl*stem] .KF/.KE floating keep
+. rm tbl*stem
+. di tbl*header-div
+.\}
+.if '\*(.T'html' \{\
+. nr tbl*ll \\n[.l]
+. ll 1000n
+.\}
+.HTML-IMAGE
+..
+.de tbl@top-hook
+.if \\n[tbl*have-header] \{\
+. ie \\n[.t]-\\n[tbl*header-ht]-1v .tbl*print-header
+. el .sp \\n[.t]u
+.\}
+..
+.de tbl*print-header
+.ev nf
+.tbl*header-div
+.ev
+.mk #T
+..
+.de TH
+.ie '\\n[.z]'tbl*header-div' \{\
+. nr T. 0
+. T#
+. br
+. di
+. \" A table with repeating headings requires enough room for them
+. \" and then at least one more vee for a row of data.
+. ie \\n[dn]+1v>=(\\n[.p]-\\n[FM]-\\n[HM]) \{\
+. ds tbl*err .TH repeating table heading(s) do not fit in
+. as tbl*err " page area; formatting only once
+. @error \\*[tbl*err]
+. rm tbl*err
+. ds@need \\n[dn]
+. tbl*print-header
+. \}
+. el \{\
+. nr tbl*header-ht \\n[dn]
+. ds@need \\n[dn]u+1v
+. tbl*print-header
+. nr tbl*have-header 1
+. \}
+.\}
+.el .@error-recover .TH without .TS H
+..
+.de @div-end!tbl*header-div
+.TH
+.TE
+..
+.de TE
+.ie '\\n(.z'tbl*header-div' .@error-recover .TS H but no .TH before .TE
+.el \{\
+. nr tbl*have-header 0
+. if !'\*(.T'html' \{\
+. sp \\n[DD]u
+. ns
+. \}
+.\}
+.HTML-IMAGE-END
+.if '\*(.T'html' \
+. ll \\n[tbl*ll]u
+.\" reset tabs
+.TA
+.nr tbl@within-table 0
+..
+.de tbl@bottom-hook
+.if \\n[tbl*have-header] \{\
+. nr T. 1
+. T#
+.\}
+..
+.de T&
+..
+.\" ****************************
+.\" ******** module pic ********
+.\" ****************************
+.\" Pic support.
+.\" This gets called if PS occurs before the first paragraph.
+.de PS
+.LP
+.\" cov*ab-init, called by LP, aliases PS to @PS.
+\\*[PS]\\
+..
+.\" @PS height width
+.de @PS
+.br
+.sp \\n[DD]u
+.ie !\\n[.$]=2 \{\
+. ds pic*msg .PS: expected 2 arguments, got \\n[.$]\"
+. as pic*msg ; not preprocessed with pic?\"
+. @error \\*[pic*msg]
+. rm pic*msg
+.\}
+.el \{\
+. ds@need (u;\\$1)+1v
+. in +(u;\\n[.l]-\\n[.i]-\\$2/2>?0)
+.\}
+.HTML-IMAGE
+..
+.de PF
+.HTML-IMAGE-END
+.par@reset
+..
+.de PE
+.PF
+.sp \\n[DD]u+.5m
+..
+.\" ****************************
+.\" ******** module ref ********
+.\" ****************************
+.\" Refer support.
+.mso refer-ms.tmac
+.\" ****************************
+.\" ******** module acc ********
+.\" ****************************
+.\" Accents and special characters.
+.ds Q \(lq
+.ds U \(rq
+.ds - \(em
+.\" Characters
+.\" Accents
+.de acc*over-def
+.ds \\$1 \Z'\v'(u;\w'x'*0+\En[rst]-\En[.cht])'\
+\h'(u;-\En[skw]+(-\En[.w]-\w'\\$2'/2)+\En[.csk])'\\$2'
+..
+.de acc*under-def
+.ds \\$1 \Z'\v'\En[.cdp]u'\h'(u;-\En[.w]-\w'\\$2'/2)'\\$2'
+..
+.de acc*slash-def
+.ds \\$1 \Z'\h'(u;-\En[.w]-\w'\\$2'/2)'\
+\v'(u;\En[.cdp]-\En[.cht]+\En[rst]+\En[rsb]/2)'\\$2'
+..
+.de acc*prefix-def
+.ds \\$1 \Z'\h'(u;\w'x'-\w'\\$2'/2)'\\$2'
+..
+.acc*prefix-def ' \'
+.acc*prefix-def ` \`
+.acc*prefix-def ^ ^
+.acc*prefix-def , \(ac
+.acc*prefix-def : \(ad
+.acc*prefix-def ~ ~
+.\" improved accent marks
+.de AM
+.acc*over-def ' \'
+.acc*over-def ` \`
+.acc*over-def ^ ^
+.acc*over-def ~ ~
+.acc*over-def : \(ad
+.acc*over-def v \(ah
+.acc*over-def _ \(a-
+.acc*over-def o \(ao
+.acc*under-def , \(ac
+.acc*under-def . \s[\En[.s]*8u/10u]\v'.2m'.\v'-.2m'\s0
+.acc*under-def hook \(ho
+.acc*slash-def / /
+.char \[hooko] o\E*[hook]
+.ds q \[hooko]
+.\" The idea of this definition is for the top of the 3 to be at the
+.\" x-height.
+.if !c\[yogh] .char \[yogh] \Z'\v'\w'x'*0-\En[rst]u'\s[\En[.s]*8u/10u]\
+\v'\w'3'*0+\En[rst]u'3\s0'\h'\w'\s[\En[.s]*8u/10u]3'u'
+.ds 3 \[yogh]
+.ds D- \(-D\" Icelandic uppercase eth
+.ds d- \(Sd\" Icelandic lowercase eth
+.ds Th \(TP\" Icelandic uppercase thorn
+.ds th \(Tp\" Icelandic lowercase thorn
+.ds 8 \(ss\" German double s
+.ds Ae \(AE\" AE ligature
+.ds ae \(ae\" ae ligature
+.ds Oe \(OE\" OE ligature
+.ds oe \(oe\" oe ligature
+.ds ? \(r?\" upside down ?
+.ds ! \(r!\" upside down !
+..
+.de CHECK-FOOTER-AND-KEEP
+.if '\*(.T'html' \{\
+. rm KF
+. als KF KS
+.
+. rm FS
+. de FS
+. sp
+. HTML-NS <cite>
+\\..
+. rm FE
+. de FE
+. HTML-NS </cite>
+. sp
+\\..
+.\}
+..
+.par@load-init
+.\" Local Variables:
+.\" mode: nroff
+.\" fill-column: 72
+.\" End:
+.\" vim: set filetype=groff textwidth=72: