AtPlotter(3X) AtPlotter(3X)
NAME
AtPlotter -- the Plotter widget class
SYNOPSIS
#include <X11/At/Plotter.h>
DESCRIPTION
The Plotter widget displays various plot types on a set of x-y axes.
Currently supported plots are line and bar plots. The axes are
optionally labeled, the widget displays an optional title, and plots
can be annotated with text. There is an optional legend at the right
or left hand side of the plot. Two x axes and two y axes can be
displayed each with a different range, and plots can be plotted
against either x axis and either y axis. The X axis is along the
bottom, the X2 axis along the top. The Y axis is along the left edge,
the Y2 axis is along the right edge.
The widget can produce presentation quality PostScript output of the
axes and plots.
All strings in the plot are AtText objects and have full access to the
multiple fonts and special symbols from that facility. See
AtText(3X).
This widget is the central widget of the AtPlotter widget set. It
coordinates the actions of its child widgets, and provides a Window on
which they draw. All children must be a subclass of AtPlot (which
provides the required member routines). There are conceptually two
types of children; axes (which are subclasses of AtAxisCore) and
plots. The plots access the application data, and collect minimum and
maximum values. These are merged by the AtPlotter and passed to the
axes which then decide on the appropriate scaling factors etc. The
AtPlotter then lays out the components of the graph, coordinates the
user space to pixel space conversions of all children and then
coordinates the redisplay of all children.
The axes and plots are treated as sub-objects of the widget and each
has its own set of resources. New plots types can be displayed by
subclassing an existing plot type.
CLASSES
The Plotter widget is a subclass of Constraint. The class pointer is
atPlotterWidgetClass, and the class name is AtPlotter.
RESOURCES
The Plotter widget inherits all the resources of the Core, Composite,
and Constraint widget classes. In addition, it has the following new
resources: (The axis and plot classes have their own sets of resources
- 1 - Formatted: December 13, 2025
AtPlotter(3X) AtPlotter(3X)
and the axis code in particular has a number of resources that affects
the overall operation of the graph). center tab(#); cB s s s lI lI lI
lI l l l l. AtPlotter Widget Resources Name#Class#Type#Default
XtNautoRedisplay#XtCAutoRedisplay#XtRBoolean#True
XtNbusyCallback#XtCCallback#XtRCallback#NULL
XtNbusyCursor#XtCCursor#XtRCursor#"watch"
XtNclickCallback#XtCCallback#XtRCallback#NULL
XtNclickCursor#XtCCursor#XtRCursor#"crosshair"
XtNdragCallback#XtCCallback#XtRCallback#NULL
XtNdragCursor#XtCCursor#XtRCursor#"crosshair"
XtNfontFamily#XtCFontFamily#XtRString#"new century schoolbook"
XtNlayoutCallback#XtCCallback#XtRCallback#NULL
XtNlegendColor#XtCForeground#XtRPixel#XtDefaultForeground
XtNlegendLeft#XtCLegendLeft#XtRBoolean#False
XtNlegendSize#XtCFontSize#XtRFontSize#AtFontNORMAL
XtNlegendSpacing#XtCMargin#XtRDimension#3
XtNlegendStyle#XtCFontStyle#XtRFontStyle#AtFontPLAIN
XtNlegendTitle#XtCLegendTitle#XtRString#"Legend"
XtNlegendTitleSize#XtCFontSize#XtRFontSize#AtFontNORMAL
XtNlegendTitleStyle#XtCFontStyle#XtRFontStyle#AtFontPLAIN
XtNlegendWidth#XtCLegendWidth#XtRDimension#0
XtNmarginHeight#XtCMargin#XtRDimension#3
XtNmarginWidth#XtCMargin#XtRDimension#3
XtNmotionCallback#XtCCallback#XtRCallback#NULL
XtNmotionCursor#XtCCursor#XtRCursor#"crosshair"
XtNplotAreaColor#XtCForeground#XtRPixel#XtDefaultBackground
XtNplotterCursor#XtCCursor#XtRCursor#None
XtNrankChildren#XtCRankChildren#XtRBoolean#False
XtNshowLegend#XtCShowLegend#XtRBoolean#True
XtNshowTitle#XtCShowTitle#XtRBoolean#True
XtNselectCallback#XtCCallback#XtRCallback#NULL
XtNselectCursor#XtCCursor#XtRCursor#"hand1"
XtNslideCallback#XtCCallback#XtRCallback#NULL
XtNslideCursor#XtCCursor#XtRCursor#"fleur"
XtNtitle#XtCTitle#XtRString#NULL
XtNtitleColor#XtCForeground#XtRPixel#XtDefaultForeground
XtNtitleHeight#XtCTitleHeight#XtRDimension#0
XtNtitleSize#XtCFontSize#XtRFontSize#AtFontBIG
XtNtitleStyle#XtCFontStyle#XtRFontStyle#AtFontPLAIN
XtNuseCursors#XtCUseCursors#XtRBoolean#True
XtNusePixmap#XtCUsePixmap#XtRBoolean#False
XtNx2Axis#XtCX2Axis#XtRWidget#NULL XtNxAxis#XtCXAxis#XtRWidget#NULL
XtNy2Axis#XtCY2Axis#XtRWidget#NULL XtNyAxis#XtCYAxis#XtRWidget#NULL
XtNautoRedisplay
Specifies whether all changes in the graph should be displayed
immediately. Setting this resource to False before doing changes
on multiple plotter child widgets which require redisplay,
reduces flickering. When all changes are done this resource
- 2 - Formatted: December 13, 2025
AtPlotter(3X) AtPlotter(3X)
should be set to True for redisplaying the entire graph.
XtNbusyCallback
Specifies procedures to be called when the plotter enters and
leaves his often time consuming display procedure. See the
section on CALLBACK INFORMATION below.
XtNbusyCursor
Specifies the cursor to be used in the plotter window when the
plotter is in his display procedure.
XtNclickCallback
Specifies procedures to be called when mouse button one is
clicked on the plotting area. This callback may be used to get
the current position of the pointer on the plotting area. See
the section on CALLBACK INFORMATION below.
XtNclickCursor
Specifies the cursor to be used in the plotter window when mouse
button one is clicked on the plotting area and procedures in the
click callback list are defined.
XtNdragCallback
Specifies procedures to be called when mouse button one is
dragged over the plotting area. This callback may be used to get
a rectangle on the plotting area, i.e. for further zooming. See
the section on CALLBACK INFORMATION below.
XtNdragCursor
Specifies the initial cursor to be used in the plotter window
when starting dragging over the plotting area an procedures in
the drag callback list are defined.
XtNfontFamily
Specifies what font family should be used to display the Plotter.
This is (by default) inherited by all children that need text
display.
XtNlayoutCallback
Specifies procedures to be called when the plotter is
recalculating his layout. This callback may be used to get and
set the pixel positions of the axes in the plotter window, i.e.
for aligning axis positions of multiple plotters. See the
- 3 - Formatted: December 13, 2025
AtPlotter(3X) AtPlotter(3X)
section on CALLBACK INFORMATION below.
XtNlegendColor
Specifies the color of the legend text entries.
XtNlegendLeft
Specifies whether the legend should be drawn at the left hand
side of the plotting area.
XtNlegendSize
Specifies the initial font size to use for the legend entries.
XtNlegendSpacing
Specifies the number of pixels to be inserted vertically between
entries in the legend.
XtNlegendStyle
Specifies the initial font style to use for the legend entries.
XtNlegendTitle
The legend title to be displayed centered in the legend area to
the right of the plot area.
XtNlegendTitleSize
Specifies the initial font size for the legend title.
XtNlegendTitleStyle
Specifies the initial font style for the legend title.
XtNlegendWidth
Specifies the number of pixels that should be reserved on the
right or left hand side of the widget for the legend. The
default value 0 means the legend width will be calculated
automatically.
XtNmarginHeight
Specifies the height in pixels of the margins in the widget.
XtNmarginWidth
Specifies the width in pixels of the margins in the widget.
- 4 - Formatted: December 13, 2025
AtPlotter(3X) AtPlotter(3X)
XtNmotionCallback
Specifies procedures to be called when mouse motion events occur
over the plotting area. This callback may be used to follow and
to get the current pointer position on the plotting area. See
the section on CALLBACK INFORMATION below.
XtNmotionCursor
Specifies the cursor to be used in the plotter window when
procedures in the motion callback list are defined.
XtNplotAreaColor
Specifies the background color of the plotting area.
XtNplotterCursor
Specifies the cursor to be used in the plotter window.
XtNrankChildren
Specifies the order that plots are drawn (in the case of
exposures or incremental updates, for instance). If False, plots
are drawn in the order they are created. If True, each plot can
be ranked with an integer that specifies its redraw priority with
the constraint resource XtNrankOrder (see CONSTRAINT RESOURCES
below). This functionality is useful when overlapping AtBarPlot
children are being drawn. By using XtNrankOrder, the user can
control the "stacking order" of the bar plots. The plot with the
lowest XtNrankOrder is drawn first (i.e. "on the bottom"), and
the plot with the highest XtNrankOrder will be drawn last (i.e.
"on top"). Plots with the same rank order are drawn in
unspecified order.
XtNshowLegend
Specifies whether the legend should be drawn.
XtNshowTitle
Specified whether the title should be drawn.
XtNselectCallback
Specifies procedures to be called when mouse button one is
clicked or dragged over the legend. This callback may be used to
select a line plot widget for further processing. See the
section on CALLBACK INFORMATION below.
- 5 - Formatted: December 13, 2025
AtPlotter(3X) AtPlotter(3X)
XtNselectCursor
Specifies the cursor to be used in the plotter window when mouse
button onw is clicked on the legend and procedures in the legend
callback list are defined.
XtNslideCallback
Specifies procedures to be called when mouse button two is
dragged over the plotting area. This callback may be used to
slide a previously selected rectangle over the plotting area,
i.e. for sliding the zoom range. See the section on CALLBACK
INFORMATION below.
XtNslideCursor
Specifies the cursor to be used in the plotter window when mouse
button two is clicked on the plotting area and procedures in the
slide callback list are defined.
XtNtitle
The title to be displayed centered above the plotting area of the
widget.
XtNtitleColor
Specifies the color of the title.
XtNtitleHeight
Specifies the number of pixels that should be reserved on the top
of the widget for the title. The default value 0 means the title
height will be calculated automatically.
XtNtitleSize
Specifies the initial font size for the title.
XtNtitleStyle
Specifies the initial font style for the title.
XtNuseCursors
Specifies whether own cursors should be used in the plotter
window.
XtNusePixmap
Specifies whether the plotter should do all drawing to a pixmap
instead of drawing to the plotter window directly. Drawing to a
- 6 - Formatted: December 13, 2025
AtPlotter(3X) AtPlotter(3X)
pixmap reduces flickering and may be very useful if plots often
change. Unfortunately, pixmaps require a lot of memory,
especially on color terminals.
XtNxAxis
XtNx2Axis
XtNyAxis
XtNy2Axis
The AtAxisCore widget corresponding to the plotter widgets axis.
A widget of a subclass of AtAxisCore should be created and
attached to the AtPlotter with these resources before any plot
child is scaled against that axis. These resources can also be
used to retrieve the current axis widget. Note that as the axis
widgets must be children of the plot widget, these resources
cannot be set at widget creation time.
PLOTTER CONSTRAINT RESOURCES
The AtPlotter widget is a constraint widget, which means that it
provides resources that each of its children (the individual plots and
axes that are displayed in the plotter) can set. They are:
center tab(#); cB s s s lI lI lI lI l l l l. AtPlotterWidget
Constraint Resources Name#Class#Type#Default
XtNdisplayed#XtCDisplayed#XtRBoolean#True
XtNlegendName#XtCLegendName#XtRString#NULL
XtNrankOrder#XtCRankOrder#XtRInt#0
XtNuseX2Axis#XtCUseX2Axis#XtRBoolean#False
XtNuseY2Axis#XtCUseY2Axis#XtRBoolean#False
XtNdisplayed
Specifies whether the child should be displayed or not. Since
plots are Xt objects rather than true widgets, they cannot be
managed and unmanaged to make them appear and disappear. This
resource provides the equivalent functionality.
XtNlegendName
Specifies the name of the plot as it should appear in the
plotter's legend.
XtNrankOrder
Specifies the the relative redrawing priority of the plot. The
highest ranking plot (of the plots in a single AtPlotterWidget)
- 7 - Formatted: December 13, 2025
AtPlotter(3X) AtPlotter(3X)
is drawn last (i.e. "on top"). The lowest ranking plot is drawn
first (i.e. "on the bottom"). This functionality is useful when
overlapping AtBarPlot plots are being drawn, as this resource
controls which plots overlap each other. If the XtNrankChildren
resource of the parent AtPlotterWidget is False, this resource is
ignored.
XtNuseX2Axis
XtNuseY2Axis
These resources specify which of the two axes this plot should be
scaled against.
PUBLIC ROUTINES
void AtPlotterDrawPS(f, pw, x1, y1, x2, y2)
void AtPlotterGeneratePostscript(filename, pw, title, x1, y1, x2, y2, landscape)
FILE *f;
AtPlotterWidget pw;
char *filename;
char *title;
int x1, y1, x2, y2;
int landscape;
AtPlotterGeneratePostscript()
Opens filename and writes the PostScript representation of
plotter pw to the file. The plotter will have title as a title.
The representation will be drawn inside the bounding box
described by (x1, y1) and (x2, y2). If landscape is True, the
plotter representation will be rotated and drawn in Landscape
mode.
AtPlotterDrawPS()
Writes the PostScript representation of plotter pw to the file
pointer fp. The plotter representation will be drawn inside the
bounding box described by (x1, y1) and (x2, y2).
Boolean AtPlotterGetAxisPositions(pw, positions)
void AtPlotterSetAxisPositions(pw, positions)
AtPlotterWidget pw;
AtAxisPositions positions;
AtPlotterGetAxisPositions()
Calculates and returns the current axis positions of the plotter
pw in positions.
- 8 - Formatted: December 13, 2025
AtPlotter(3X) AtPlotter(3X)
AtPlotterSetAxisPositions()
Set the axis positions of plotter pw as defined in positionsP.
The data type AtAxisPositions is defined as below:
typedef struct {
char position;
Position xaxis, x2axis;
Position yaxis, y2axis;
} AtAxisPositions;
position
Defines a mask which denotes the positions which should be set.
Legal values for the position mask are AtPositionNONE if there is
no position to set, AtPositionXAXES if the positions of the X
axes are to be set, and AtPositionYAXES if the positions of the Y
axes are to be set.
xaxis, x2axis
Indicate the pixel positions of the X axes in the plotter window,
or in other words, the bottom and top positions of the plotting
area.
yaxis, y2axis
Indicate the pixel positions of the Y axes in the plotter window,
or in other words, the left and right positions of the plotting
area.
These routines may be used in conjunction with procedures defined in
the layout callback list to get and set the pixel positions of the X
and Y axes, i.e. for aligning the axis positions when using multiple
plotters in one application. For the layout callback see section
CALLBACK INFORMATION below.
Dimension AtPlotterGetLegendWidth(pw)
Dimension AtPlotterGetTitleHeight(pw)
AtPlotterWidget pw;
AtPlotterGetLegendWidth()
Calculates and returns the maximal width of the legend.
AtPlotterGetTitleHeight()
Returns the calculated height of the title.
- 9 - Formatted: December 13, 2025
AtPlotter(3X) AtPlotter(3X)
Widget AtPlotterGetSelectedPlot(pw)
Boolean AtPlotterSetSelectedPlot(pw, widget)
AtPlotterWidget pw;
Widget widget;
AtPlotterGetSelectedPlot()
Returns the currently selected plot widget, or NULL if there is
no widget selected.
AtPlotterSetSelectedPlot()
Causes the plotter to select the plot widget widget , and returns
True if this was possible, False otherwise.
PLOTTER ROUTINES
These routines are publicly visible, but are intended for
communication within the plotter widget set (primarily for children to
request updates of various sorts). It is not intended that
applications call these routines.
void AtPlotterPlotExtended(cw, bb, from, to)
void AtPlotterPlotDataChanged(cw, bb, refresh)
void AtPlotterRefreshRequired(cw)
void AtPlotterRedrawRequired(cw)
void AtPlotterLayoutRequired(cw)
void AtPlotterRescaleRequired(cw)
void AtPlotterRecalcThisPlot(cw)
AtPlotWidget cw;
BoundingBox *bb;
int from, to;
int refresh;
AtPlotterPlotExtended()
This child plot has just been extended, and the new elements
(numbered from to through) have the bounding box bb. This is
used by the AtSPlot and AtXYPlot classes.
AtPlotterPlotDataChanged()
The data for this plot has changed and the new bounding box is
bb. refresh is true if the child plot believes it can redraw the
changed graph without a full erase and redraw being required
(e.g. becuase the XtNfastUpdate resource is set on that child).
- 10 - Formatted: December 13, 2025
AtPlotter(3X) AtPlotter(3X)
AtPlotterRefreshRequired()
This child requires to be redrawn but doen't need the rest of the
plot to be redrawn. Usually because of a color change or
similar.
AtPlotterRedrawRequired()
This child requires the whole plot to be redrawn, but no user to
pixel conversions done. Usually because something like line
style changed.
AtPlotterLayoutRequired()
The pixel positions of the graph elements have probably changed,
so the graph needs to be laid out again. Usually the result of
changing axis resorces which change the width of the axis.
Resizing the widget (either from the program or via the window
manager) will force the layout also.
AtPlotterRescaleRequired()
The minimum and maximum of the axes should be recalculated
because the resources that control this have changed. This is
called by axes; the plots themselves communicate via
AtPlotDataChanged (to pass bounding box information).
AtPlotterRecalcThisPlot()
Something that affects the user to pixel conversion for this
child has changed, but it won't change the scaling of other
children or the pixel locations of any element. The result of
changing the tic label resources.
DEFAULT TRANSLATIONS
tab(#); l l. <Btn1Down>:#start-selection() <Btn1Motion>:#drag()
<Btn1Up>:#end-selection() <Btn2Down>:#start-sliding()
<Btn2Motion>:#slide() <Btn2Up>:#end-sliding() <Btn3Down>:#cancel()
<Key>Escape:#cancel() <Motion>:#motion-notify()
USAGE
plotter = XtCreateWidget(plotter_name, AtPlotterWidgetClass, parent, args, num_args)
String plotter_name;
WidgetClass atPlotterWidgetClass;
Widget parent;
ArgList args;
Cardinal num_args;
- 11 - Formatted: December 13, 2025
AtPlotter(3X) AtPlotter(3X)
CALLBACK INFORMATION
The XtNlayoutCallback list is called after the plotter has calculated
his layout and before the plotter starts his display process. The
call_data argument to this callback is of type AtAxisPositions as
described above in the section PUBLIC ROUTINES. When using multiple
plotters in one application it may be necessary to align the pixel
positions of the plotter axes. This callback may be used in
conjunction with the routines AtPlotterGetPositions() and
AtPlotterSetPositions() to request the axis positions of all
interesting plotters, to calculate the required min and max positions,
and then to set these positions setting the mask position and the
appropriate position values.
The XtNbusyCallback list is called when the plotter enters and leaves
his often time consuming display procedure. The call_data argument to
this callback is of type AtBusyCallbackData:
typedef struct {
int reason;
Boolean busy;
} AtBusyCallbackData;
reason
Has the value AtBusyPLOTTER if the callback list procedures are
called from within the plotter's redisplay routine, and has the
value AtBusyPOSTSCRIPT if they are called from within the
plotter's PostScript output routines.
busy Has the value True when the plotter enters his display procedure
and starts calculating his layout and drawing. When leaving his
display procedure busy is set to False.
The XtNmotionCallback list is called when mouse motion events occur
over the plotting area and may be used to follow the pointer and to
get the current pointer position in pixels and/or user coordinates.
The call_data argument to this callback is of type
AtPointCallbackData:
typedef struct {
int reason;
Position pixelx, pixely;
double x1, y1;
double x2, y2;
} AtPointCallbackData;
- 12 - Formatted: December 13, 2025
AtPlotter(3X) AtPlotter(3X)
reason
Has the value AtPointMOTION.
pixelx, pixely
Indicate the window pixel x and y values of the pointer.
x1, y1
Indicate the user coordinates x and y scaled against the first x
and y axis.
x2, y2
Indicate the user coordinates x and y scaled against the second x
and y axis. These values default to 0.0 if no second x or y axis
is attached to plotter.
The XtNclickCallback list is called when mouse button one is clicked
within the plotting area. e.g. to get the current pointer position.
The call_data argument to this callback is also of type
AtPointCallbackData (see above). The reason item then has the value
AtPointCLICK.
The XtNdragCallback list is called when mouse button one is dragged
over the plotting area and may be used to get a range or rectangle of
the plotting area, i.e. for further zooming. The call_data argument
to this callback is of type AtRectangleCallbackData:
typedef struct {
int reason;
Position pixelx1, pixely1;
Position pixelx2, pixely2;
double x11, y11, x12, y12;
double x21, y21, x22, y22;
} AtRectangleCallbackData;
reason
Has the value AtRectangleDRAG.
pixelx1, pixely1
Indicate the window pixel x and y values of the upper left corner
of the drag rectangle.
pixelx2, pixely2
Indicate the window pixel x and y values of the lower right
corner of the drag rectangle.
- 13 - Formatted: December 13, 2025
AtPlotter(3X) AtPlotter(3X)
x11, y11
Indicate the user coordinates x and y scaled against the first x
and y axis of the upper left right corner of the drag rectangle.
x12, y12
Indicate the user coordinates x and y scaled against the first x
and y axis of the lower right corner of the drag rectangle.
x21, y21
Indicate the user coordinates x and y scaled against the second x
and y axes of the upper left right corner of the drag rectangle.
x22, y22
Indicate the user coordinates x and y scaled against the second x
and y axes of the lower right corner of the drag rectangle.
The XtNslideCallback list is called when mouse button two is dragged
over the plotting area and may be used to slide a previously selected
range or rectangle over the plotting area, i.e. for sliding the
zooming area. The call_data argument to this callback also is of type
AtRectangleCallbackData. The reason item has the value
AtRectangleSLIDE.
The XtNselectCallback list is called when mouse button one is clicked
or dragged over the legend and may be used to select a plot widget for
further processing. Deselecting an already selected plot widget may
be done by clicking on the legend title. The call_data argument to
this callback is of type AtSelectCallbackData:
typedef struct {
int reason;
Widget widget;
} AtSelectCallbackData;
reason
Has the value AtSelectSELECTED if a plot widget was selected, and
the value AtSelectDESELECTED if no selection was done or a
selected plot widget was deselected.
widget
Indicates the selected plot widget or NULL if no widget was
selected.
- 14 - Formatted: December 13, 2025
AtPlotter(3X) AtPlotter(3X)
SEE ALSO
AtText(3X), AtFontFamily(3X), AtPlot(3X), AtAxisCore(3X), AtSPlot(3X),
AtXYPlot(3X)
``Using The AthenaTools Plotter Widget Set''
AUTHORS
David Flanagan (MIT Project Athena), Chris Craig (MIT Project Athena),
and Kambiz Soroushian (MIT Project Athena) wrote the code for version
V4. The version V5-beta was substantially rewritten by Gregory Bond,
Burdett, Buckeridge and Young Ltd. (gnb@bby.oz.au). Re-additon of
callbacks (from V4) and other changes and improvements for version
V6.0 were done by Peter Klingebiel, University of Paderborn
(klin@iat.uni-paderborn.de).
NOTES
PostScript is a trademark of Adobe Systems Incorporated.
COPYRIGHT
Copyright 1990,1991 by the Massachusetts Institute of Technology
Copyright 1991 by Burdett, Buckeridge and Young Ltd.
Copyright 1992 by University of Paderborn
All rights reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of the firms, institutes
or employers of the authors not be used in advertising or publicity
pertaining to distribution of the software without specific, written
prior permission.
THE AUTHORS AND THEIR FIRMS, INSTITUTES OR EMPLOYERS DISCLAIM ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE
AUTHORS AND THEIR FIRMS, INSTITUTES OR EMPLOYERS BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- 15 - Formatted: December 13, 2025