<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.fairwayfarmsswimclub.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Matt+Parnell</id>
	<title>Fairway Farms Swim Club - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.fairwayfarmsswimclub.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Matt+Parnell"/>
	<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/Special:Contributions/Matt_Parnell"/>
	<updated>2026-06-10T11:54:41Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=File:FFSC-001_Pg_10_-_Filter_Tank_Pressure_Sensors.png&amp;diff=1789</id>
		<title>File:FFSC-001 Pg 10 - Filter Tank Pressure Sensors.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=File:FFSC-001_Pg_10_-_Filter_Tank_Pressure_Sensors.png&amp;diff=1789"/>
		<updated>2026-04-29T00:14:07Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: Matt Parnell uploaded a new version of File:FFSC-001 Pg 10 - Filter Tank Pressure Sensors.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
FFSC-001 Pg 10 - Filter Tank Pressure Sensors&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Systems_Dashboard&amp;diff=1780</id>
		<title>Pool Systems Dashboard</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Systems_Dashboard&amp;diff=1780"/>
		<updated>2025-06-30T18:45:53Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: /* Graphs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The dashboard provides a visual interface for the [[Pool Systems Automation]].&lt;br /&gt;
&lt;br /&gt;
== System ==&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
&lt;br /&gt;
The hardware is responsible for data collection and display of the dashboard.  It is located on the south wall of the pump house.&lt;br /&gt;
&lt;br /&gt;
==== Raspberry Pi ====&lt;br /&gt;
&lt;br /&gt;
The dashboard presently runs on a [https://www.raspberrypi.com/products/raspberry-pi-5/ Raspberry Pi 5] (4 GB).  The Pi hardware was upgraded in 2025; previously it ran on a [https://www.raspberrypi.org/products/raspberry-pi-3-model-b/ Raspberry Pi 3 Model B] V1.2.&lt;br /&gt;
&lt;br /&gt;
The Pi is powered via a modified USB-C cable, connected to a Mean Well DDR-15G-5.  Note that previously, a a micro USB cable was used for the Pi 3B.  This device drops the 12 V chassis supply down to 5 V (for the Pi) and is capable of producing 15 W (3 A).  This exceeds the 2.5 A requirement cited for the Pi.  The internal WiFi radio is NOT used; instead, network connectivity is provided by Ethernet (to the Lantronix PremierWave XN).&lt;br /&gt;
&lt;br /&gt;
Communication with the [[Pool Systems Automation#Programmable Logic Controller|Programmable Logic Controller]] and [[Pool Boiler Temperature Controller|Temperature Controller]] requires a functional WiFi device network.&lt;br /&gt;
&lt;br /&gt;
==== Lantronix PremierWave XN ====&lt;br /&gt;
&lt;br /&gt;
The Lantronix PremierWave XN in the chassis with the Raspberry Pi has multiple purposes:&lt;br /&gt;
&lt;br /&gt;
* To provide serial-to-IP conversion for the RS-485 port on the [[Chemtrol Pool Controller]].&lt;br /&gt;
* To provide a link to the WiFi device network.&lt;br /&gt;
* To provide an Ethernet port, bridging/routing WiFi to the connected device.&lt;br /&gt;
&lt;br /&gt;
==== BeagleBone Black ====&lt;br /&gt;
&lt;br /&gt;
In the early trials, a [https://beagleboard.org/black BeagleBone Black] board was used.  Unfortunately, it had two significant limitations:&lt;br /&gt;
&lt;br /&gt;
* A lack of 1080p (or better) monitor support.  The proved problematic, as the HP Compaq LA2405x has a 1920x1200 native resolution.  The pixel clock on the CPU is limited to 126.5 MHz.  1920x1080x60 requires a pixel clock of 173 MHz; clearly 1920x1200 requires an even higher frequency pixel clock.  This was discussed with one of the main developers [https://forum.beagleboard.org/t/1680x1050x60-resolution-via-hdmi/2692/2 here].&lt;br /&gt;
* A single-core CPU.  As it turns out, the dashboard software requires a lot of CPU time to render in a browser.  So much so that a single core simply couldn&#039;t keep up; render times exceeded 30 seconds as I recall.  By using a CPU with multiple cores, the multiple threads of work can be spread out and processed in parallel.&lt;br /&gt;
&lt;br /&gt;
Both limitations aside, the BeagleBone Black is a fantastic piece of hardware, it just wasn&#039;t ideally suited for this project.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
&lt;br /&gt;
All software operates on [https://www.raspberrypi.org/software/operating-systems/ Raspberry Pi OS] (the &amp;quot;Lite&amp;quot; distribution), which is based on Debian GNU/Linux.&lt;br /&gt;
&lt;br /&gt;
==== InfluxDB ====&lt;br /&gt;
&lt;br /&gt;
[https://www.influxdata.com/products/influxdb-overview/ InfluxDB] is a time series database, used to store data collected by [https://www.influxdata.com/time-series-platform/telegraf/ Telegraf].&lt;br /&gt;
&lt;br /&gt;
Previously, [https://www.influxdata.com/time-series-platform/chronograf/ Chronograf] was used to display the data in a visually useful way on the dashboard.  [https://www.influxdata.com/time-series-platform/kapacitor/ Kapacitor] was used to trigger actions based upon data values.&lt;br /&gt;
&lt;br /&gt;
==== Grafana ====&lt;br /&gt;
&lt;br /&gt;
In the Pi 5 refresh, the Chronograf/Kapacitor portion of the InfluxDB TICK stack were replaced with [https://grafana.com/ Grafana].  This seems to be the preferred direction for InfluxDB 3 onward.  Grafana offers far more DB (input) hooks than Chronograf.&lt;br /&gt;
&lt;br /&gt;
==== Node-RED ====&lt;br /&gt;
&lt;br /&gt;
[https://nodered.org/ Node-RED] is used to request and interpret data from the [[Chemtrol Pool Controller]] via its RS-485 interface (over Ethernet).&lt;br /&gt;
&lt;br /&gt;
=== LCD Monitor ===&lt;br /&gt;
&lt;br /&gt;
The monitor is an &amp;quot;old&amp;quot; HP Compaq LA2405x.  This was an older surplus unit, installed in 2021.  It is/was fully expected that this monitor may eventually fail due to the corrosive environment it&#039;s exposed to in the summer, along with a cold/damp/unconditioned environment in the winter.  That said, it&#039;s still going strong as of 2025.  Replacement is straightforward; screws accessible on the bottom side release it from the VESA wall mount.  Any monitor with HD or better resolution and an HDMI input should suffice.&lt;br /&gt;
&lt;br /&gt;
== Gauges ==&lt;br /&gt;
&lt;br /&gt;
Gauge measurements are averaged in both the PLC and dashboard software.  Gauges may take several seconds (or longer) to respond to significant changes in system conditions.&lt;br /&gt;
&lt;br /&gt;
=== Filter Tank Pressure ===&lt;br /&gt;
&lt;br /&gt;
Shows the pressure in pounds per square inch (psi) for a [[Sand Filters|sand filter]] tank per the PLC [[Pool Systems Automation#Filter Tank Pressure|Filter Tank Pressure]] measurement (via WiFi link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(psi)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0-4&lt;br /&gt;
|Red&lt;br /&gt;
|Critically Low Pressure (Pump/Flow Issue)&lt;br /&gt;
|-&lt;br /&gt;
|4-8&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Pressure (Flow Issue) - Consider [[Cleaning the Strainer Basket]]&lt;br /&gt;
|-&lt;br /&gt;
|8-18&lt;br /&gt;
|Green&lt;br /&gt;
|Normal Operating Pressure&lt;br /&gt;
|-&lt;br /&gt;
|18+&lt;br /&gt;
|Yellow/Red&lt;br /&gt;
|[[Backwashing|Backwash]] Recommended&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For consistent indication, the values above and dashboard visualization thresholds should always align with those defined within the [[Pool Systems Automation#Filter Tank Pressure|PLC thresholds]].&lt;br /&gt;
&lt;br /&gt;
Tank pressure is lowest when the [[Cleaning the Strainer Basket|strainer basket is clean]] and the sand filters have been recently [[Backwashing|backwashed]].  If pump outflow is restricted enough (in an effort to [[Pool Main Pump#Flow Rate|maintain proper flow]], it is possible for pressure to dip into the &amp;quot;Low Pressure&amp;quot; range.  This is not necessarily a cause for any concern.&lt;br /&gt;
&lt;br /&gt;
If the associated sensor is in a fault state (the sensor has failed, there is a wiring/fuse fault or the connector is unplugged), the gauge will show a value of 0.0.  A fault state is indicated by the PLC and the stack light.  If the gauge is not visible (the block is blank), a communication error with the PLC has occurred or a software issue is present on the dashboard PC.  Consult the system administrator.&lt;br /&gt;
&lt;br /&gt;
=== Surge Tank Level ===&lt;br /&gt;
&lt;br /&gt;
Shows the level (depth) in inches for the surge tank per the PLC [[Pool Systems Automation#Surge Tank Level|Surge Tank Level]] measurement (via WiFi link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(in)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 16&lt;br /&gt;
|Red&lt;br /&gt;
|Critical Level&lt;br /&gt;
|-&lt;br /&gt;
|16-46&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Level (Auto-Fill Threshold)&lt;br /&gt;
|-&lt;br /&gt;
|46-60&lt;br /&gt;
|Green&lt;br /&gt;
|Nominal Level (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|60-76&lt;br /&gt;
|Blue&lt;br /&gt;
|Excess Level&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 76&lt;br /&gt;
|Red&lt;br /&gt;
|Overflow Level&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:  The &amp;quot;Nominal Level&amp;quot; of the surge tank is subject to future revision.  At this time, lacking a proper drain modulating valve, it is not possible to provide &amp;quot;surge&amp;quot; capacity (keep the tank level lowered during periods of high gutter flow).  As a result, some portion of the &amp;quot;Nominal Level&amp;quot; and &amp;quot;Excess Level&amp;quot; is expected when the pool level is high and/or there is a large amount of activity in the pool.  Ideally, the surge tank should usually remain below the gutter inlet level.&lt;br /&gt;
&lt;br /&gt;
When the &amp;quot;Critical Level&amp;quot; threshold is met, this may result in pump shutdown (per the PLC) to prevent pulling air into the pump.  The surge tank water level is insufficient to maintain operation.  When enabled, auto-fill begins at the upper end of the &amp;quot;Low Level&amp;quot; threshold and ends when the upper end of the &amp;quot;Nominal Level&amp;quot; is met.  A large amount of surge tank level hysteresis is needed when an actual pool level measurement is lacking.&lt;br /&gt;
&lt;br /&gt;
The tank nears overflow at the &amp;quot;Overflow Level&amp;quot; threshold.  No specific action is taken by the PLC at this point.&lt;br /&gt;
&lt;br /&gt;
=== Out Flow ===&lt;br /&gt;
&lt;br /&gt;
Shows the out flow rate in gallons per minute (GPM).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 490&lt;br /&gt;
|Red&lt;br /&gt;
|Very Low Flow&lt;br /&gt;
|-&lt;br /&gt;
|490-570&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Flow (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|570-670&lt;br /&gt;
|Green&lt;br /&gt;
|Optimal Flow&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 670&lt;br /&gt;
|Yellow&lt;br /&gt;
|High Flow&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A target flow rate of 600 GPM has been established for manual adjustment.  This flow rate:&lt;br /&gt;
&lt;br /&gt;
* Meets the minimum pool turnover rate of 4 times per day (every 6 hours) for a 203,500 gallon pool.&lt;br /&gt;
* Is within some margin of the maximum flow rate set by the sand filters (140 GPM x 4 = 580 GPM).&lt;br /&gt;
&lt;br /&gt;
To prevent [[Sand Filters#Channeling|channeling]] in the sand filters, an upper bound of 670 GPM has been set (somewhat arbitrarily).  The operator should try to keep as close to 600 GPM operation as possible (without dipping below 570 GPM).&lt;br /&gt;
&lt;br /&gt;
=== Inlet Temperature ===&lt;br /&gt;
&lt;br /&gt;
Shows the inlet temperature in degrees Fahrenheit (&amp;amp;deg;F) per the temperature controller measurement (via WiFi link).  This temperature is measured directly after the filter tanks, prior to the boiler loop (refer to the [[Process Flow Diagram]]).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 79&lt;br /&gt;
|Blue&lt;br /&gt;
|Low Temperature (Temperature Controller Alarm)&lt;br /&gt;
|-&lt;br /&gt;
|79-81&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Temperature (Outside of Controlled Bounds)&lt;br /&gt;
|-&lt;br /&gt;
|81+&lt;br /&gt;
|Green&lt;br /&gt;
|Normal Temperature&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The boiler is nominally set to 82 &amp;amp;deg;F.  Controller hysteresis keeps the temperature to within &amp;amp;plusmn;1 &amp;amp;deg;F or less.  The temperature controller enters an &amp;quot;alarm&amp;quot; state indicating that the boiler may be in a fault state once the temperature is below 79 &amp;amp;deg;F.  During hot summer days, temperatures of 82 &amp;amp;deg;F to 87 &amp;amp;deg;F are expected and normal.&lt;br /&gt;
&lt;br /&gt;
=== pH ===&lt;br /&gt;
&lt;br /&gt;
Shows the sampled water pH per a [[Chemtrol Pool Controller]] measurement (via RS-485/Ethernet link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 7.2&lt;br /&gt;
|Red&lt;br /&gt;
|Corrosive Water (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|7.2-7.4&lt;br /&gt;
|Yellow&lt;br /&gt;
|pH Low&lt;br /&gt;
|-&lt;br /&gt;
|7.4-7.6&lt;br /&gt;
|Green&lt;br /&gt;
|pH Ideal&lt;br /&gt;
|-&lt;br /&gt;
|7.6-7.8&lt;br /&gt;
|Yellow&lt;br /&gt;
|pH High&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 7.8&lt;br /&gt;
|Red&lt;br /&gt;
|Scaling Water (See Note)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: Ideal pH is between 7.4 and 7.6.  A pH between 7.2 and 7.8 is generally acceptable (though possibly too low or too high).  A pH below 7.2 or above 7.8 may be problematic; verify by calculating the Langelier Saturation Index (LSI).&lt;br /&gt;
&lt;br /&gt;
=== ORP ===&lt;br /&gt;
&lt;br /&gt;
Shows the sampled water oxidation reduction potential (ORP) per a [[Chemtrol Pool Controller]] measurement (via RS-485/Ethernet link).&lt;br /&gt;
&lt;br /&gt;
== Graphs ==&lt;br /&gt;
&lt;br /&gt;
To be updated.&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Systems_Dashboard&amp;diff=1779</id>
		<title>Pool Systems Dashboard</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Systems_Dashboard&amp;diff=1779"/>
		<updated>2025-06-30T18:44:24Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: /* Gauges */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The dashboard provides a visual interface for the [[Pool Systems Automation]].&lt;br /&gt;
&lt;br /&gt;
== System ==&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
&lt;br /&gt;
The hardware is responsible for data collection and display of the dashboard.  It is located on the south wall of the pump house.&lt;br /&gt;
&lt;br /&gt;
==== Raspberry Pi ====&lt;br /&gt;
&lt;br /&gt;
The dashboard presently runs on a [https://www.raspberrypi.com/products/raspberry-pi-5/ Raspberry Pi 5] (4 GB).  The Pi hardware was upgraded in 2025; previously it ran on a [https://www.raspberrypi.org/products/raspberry-pi-3-model-b/ Raspberry Pi 3 Model B] V1.2.&lt;br /&gt;
&lt;br /&gt;
The Pi is powered via a modified USB-C cable, connected to a Mean Well DDR-15G-5.  Note that previously, a a micro USB cable was used for the Pi 3B.  This device drops the 12 V chassis supply down to 5 V (for the Pi) and is capable of producing 15 W (3 A).  This exceeds the 2.5 A requirement cited for the Pi.  The internal WiFi radio is NOT used; instead, network connectivity is provided by Ethernet (to the Lantronix PremierWave XN).&lt;br /&gt;
&lt;br /&gt;
Communication with the [[Pool Systems Automation#Programmable Logic Controller|Programmable Logic Controller]] and [[Pool Boiler Temperature Controller|Temperature Controller]] requires a functional WiFi device network.&lt;br /&gt;
&lt;br /&gt;
==== Lantronix PremierWave XN ====&lt;br /&gt;
&lt;br /&gt;
The Lantronix PremierWave XN in the chassis with the Raspberry Pi has multiple purposes:&lt;br /&gt;
&lt;br /&gt;
* To provide serial-to-IP conversion for the RS-485 port on the [[Chemtrol Pool Controller]].&lt;br /&gt;
* To provide a link to the WiFi device network.&lt;br /&gt;
* To provide an Ethernet port, bridging/routing WiFi to the connected device.&lt;br /&gt;
&lt;br /&gt;
==== BeagleBone Black ====&lt;br /&gt;
&lt;br /&gt;
In the early trials, a [https://beagleboard.org/black BeagleBone Black] board was used.  Unfortunately, it had two significant limitations:&lt;br /&gt;
&lt;br /&gt;
* A lack of 1080p (or better) monitor support.  The proved problematic, as the HP Compaq LA2405x has a 1920x1200 native resolution.  The pixel clock on the CPU is limited to 126.5 MHz.  1920x1080x60 requires a pixel clock of 173 MHz; clearly 1920x1200 requires an even higher frequency pixel clock.  This was discussed with one of the main developers [https://forum.beagleboard.org/t/1680x1050x60-resolution-via-hdmi/2692/2 here].&lt;br /&gt;
* A single-core CPU.  As it turns out, the dashboard software requires a lot of CPU time to render in a browser.  So much so that a single core simply couldn&#039;t keep up; render times exceeded 30 seconds as I recall.  By using a CPU with multiple cores, the multiple threads of work can be spread out and processed in parallel.&lt;br /&gt;
&lt;br /&gt;
Both limitations aside, the BeagleBone Black is a fantastic piece of hardware, it just wasn&#039;t ideally suited for this project.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
&lt;br /&gt;
All software operates on [https://www.raspberrypi.org/software/operating-systems/ Raspberry Pi OS] (the &amp;quot;Lite&amp;quot; distribution), which is based on Debian GNU/Linux.&lt;br /&gt;
&lt;br /&gt;
==== InfluxDB ====&lt;br /&gt;
&lt;br /&gt;
[https://www.influxdata.com/products/influxdb-overview/ InfluxDB] is a time series database, used to store data collected by [https://www.influxdata.com/time-series-platform/telegraf/ Telegraf].&lt;br /&gt;
&lt;br /&gt;
Previously, [https://www.influxdata.com/time-series-platform/chronograf/ Chronograf] was used to display the data in a visually useful way on the dashboard.  [https://www.influxdata.com/time-series-platform/kapacitor/ Kapacitor] was used to trigger actions based upon data values.&lt;br /&gt;
&lt;br /&gt;
==== Grafana ====&lt;br /&gt;
&lt;br /&gt;
In the Pi 5 refresh, the Chronograf/Kapacitor portion of the InfluxDB TICK stack were replaced with [https://grafana.com/ Grafana].  This seems to be the preferred direction for InfluxDB 3 onward.  Grafana offers far more DB (input) hooks than Chronograf.&lt;br /&gt;
&lt;br /&gt;
==== Node-RED ====&lt;br /&gt;
&lt;br /&gt;
[https://nodered.org/ Node-RED] is used to request and interpret data from the [[Chemtrol Pool Controller]] via its RS-485 interface (over Ethernet).&lt;br /&gt;
&lt;br /&gt;
=== LCD Monitor ===&lt;br /&gt;
&lt;br /&gt;
The monitor is an &amp;quot;old&amp;quot; HP Compaq LA2405x.  This was an older surplus unit, installed in 2021.  It is/was fully expected that this monitor may eventually fail due to the corrosive environment it&#039;s exposed to in the summer, along with a cold/damp/unconditioned environment in the winter.  That said, it&#039;s still going strong as of 2025.  Replacement is straightforward; screws accessible on the bottom side release it from the VESA wall mount.  Any monitor with HD or better resolution and an HDMI input should suffice.&lt;br /&gt;
&lt;br /&gt;
== Gauges ==&lt;br /&gt;
&lt;br /&gt;
Gauge measurements are averaged in both the PLC and dashboard software.  Gauges may take several seconds (or longer) to respond to significant changes in system conditions.&lt;br /&gt;
&lt;br /&gt;
=== Filter Tank Pressure ===&lt;br /&gt;
&lt;br /&gt;
Shows the pressure in pounds per square inch (psi) for a [[Sand Filters|sand filter]] tank per the PLC [[Pool Systems Automation#Filter Tank Pressure|Filter Tank Pressure]] measurement (via WiFi link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(psi)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0-4&lt;br /&gt;
|Red&lt;br /&gt;
|Critically Low Pressure (Pump/Flow Issue)&lt;br /&gt;
|-&lt;br /&gt;
|4-8&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Pressure (Flow Issue) - Consider [[Cleaning the Strainer Basket]]&lt;br /&gt;
|-&lt;br /&gt;
|8-18&lt;br /&gt;
|Green&lt;br /&gt;
|Normal Operating Pressure&lt;br /&gt;
|-&lt;br /&gt;
|18+&lt;br /&gt;
|Yellow/Red&lt;br /&gt;
|[[Backwashing|Backwash]] Recommended&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For consistent indication, the values above and dashboard visualization thresholds should always align with those defined within the [[Pool Systems Automation#Filter Tank Pressure|PLC thresholds]].&lt;br /&gt;
&lt;br /&gt;
Tank pressure is lowest when the [[Cleaning the Strainer Basket|strainer basket is clean]] and the sand filters have been recently [[Backwashing|backwashed]].  If pump outflow is restricted enough (in an effort to [[Pool Main Pump#Flow Rate|maintain proper flow]], it is possible for pressure to dip into the &amp;quot;Low Pressure&amp;quot; range.  This is not necessarily a cause for any concern.&lt;br /&gt;
&lt;br /&gt;
If the associated sensor is in a fault state (the sensor has failed, there is a wiring/fuse fault or the connector is unplugged), the gauge will show a value of 0.0.  A fault state is indicated by the PLC and the stack light.  If the gauge is not visible (the block is blank), a communication error with the PLC has occurred or a software issue is present on the dashboard PC.  Consult the system administrator.&lt;br /&gt;
&lt;br /&gt;
=== Surge Tank Level ===&lt;br /&gt;
&lt;br /&gt;
Shows the level (depth) in inches for the surge tank per the PLC [[Pool Systems Automation#Surge Tank Level|Surge Tank Level]] measurement (via WiFi link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(in)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 16&lt;br /&gt;
|Red&lt;br /&gt;
|Critical Level&lt;br /&gt;
|-&lt;br /&gt;
|16-46&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Level (Auto-Fill Threshold)&lt;br /&gt;
|-&lt;br /&gt;
|46-60&lt;br /&gt;
|Green&lt;br /&gt;
|Nominal Level (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|60-76&lt;br /&gt;
|Blue&lt;br /&gt;
|Excess Level&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 76&lt;br /&gt;
|Red&lt;br /&gt;
|Overflow Level&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:  The &amp;quot;Nominal Level&amp;quot; of the surge tank is subject to future revision.  At this time, lacking a proper drain modulating valve, it is not possible to provide &amp;quot;surge&amp;quot; capacity (keep the tank level lowered during periods of high gutter flow).  As a result, some portion of the &amp;quot;Nominal Level&amp;quot; and &amp;quot;Excess Level&amp;quot; is expected when the pool level is high and/or there is a large amount of activity in the pool.  Ideally, the surge tank should usually remain below the gutter inlet level.&lt;br /&gt;
&lt;br /&gt;
When the &amp;quot;Critical Level&amp;quot; threshold is met, this may result in pump shutdown (per the PLC) to prevent pulling air into the pump.  The surge tank water level is insufficient to maintain operation.  When enabled, auto-fill begins at the upper end of the &amp;quot;Low Level&amp;quot; threshold and ends when the upper end of the &amp;quot;Nominal Level&amp;quot; is met.  A large amount of surge tank level hysteresis is needed when an actual pool level measurement is lacking.&lt;br /&gt;
&lt;br /&gt;
The tank nears overflow at the &amp;quot;Overflow Level&amp;quot; threshold.  No specific action is taken by the PLC at this point.&lt;br /&gt;
&lt;br /&gt;
=== Out Flow ===&lt;br /&gt;
&lt;br /&gt;
Shows the out flow rate in gallons per minute (GPM).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 490&lt;br /&gt;
|Red&lt;br /&gt;
|Very Low Flow&lt;br /&gt;
|-&lt;br /&gt;
|490-570&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Flow (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|570-670&lt;br /&gt;
|Green&lt;br /&gt;
|Optimal Flow&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 670&lt;br /&gt;
|Yellow&lt;br /&gt;
|High Flow&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A target flow rate of 600 GPM has been established for manual adjustment.  This flow rate:&lt;br /&gt;
&lt;br /&gt;
* Meets the minimum pool turnover rate of 4 times per day (every 6 hours) for a 203,500 gallon pool.&lt;br /&gt;
* Is within some margin of the maximum flow rate set by the sand filters (140 GPM x 4 = 580 GPM).&lt;br /&gt;
&lt;br /&gt;
To prevent [[Sand Filters#Channeling|channeling]] in the sand filters, an upper bound of 670 GPM has been set (somewhat arbitrarily).  The operator should try to keep as close to 600 GPM operation as possible (without dipping below 570 GPM).&lt;br /&gt;
&lt;br /&gt;
=== Inlet Temperature ===&lt;br /&gt;
&lt;br /&gt;
Shows the inlet temperature in degrees Fahrenheit (&amp;amp;deg;F) per the temperature controller measurement (via WiFi link).  This temperature is measured directly after the filter tanks, prior to the boiler loop (refer to the [[Process Flow Diagram]]).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 79&lt;br /&gt;
|Blue&lt;br /&gt;
|Low Temperature (Temperature Controller Alarm)&lt;br /&gt;
|-&lt;br /&gt;
|79-81&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Temperature (Outside of Controlled Bounds)&lt;br /&gt;
|-&lt;br /&gt;
|81+&lt;br /&gt;
|Green&lt;br /&gt;
|Normal Temperature&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The boiler is nominally set to 82 &amp;amp;deg;F.  Controller hysteresis keeps the temperature to within &amp;amp;plusmn;1 &amp;amp;deg;F or less.  The temperature controller enters an &amp;quot;alarm&amp;quot; state indicating that the boiler may be in a fault state once the temperature is below 79 &amp;amp;deg;F.  During hot summer days, temperatures of 82 &amp;amp;deg;F to 87 &amp;amp;deg;F are expected and normal.&lt;br /&gt;
&lt;br /&gt;
=== pH ===&lt;br /&gt;
&lt;br /&gt;
Shows the sampled water pH per a [[Chemtrol Pool Controller]] measurement (via RS-485/Ethernet link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 7.2&lt;br /&gt;
|Red&lt;br /&gt;
|Corrosive Water (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|7.2-7.4&lt;br /&gt;
|Yellow&lt;br /&gt;
|pH Low&lt;br /&gt;
|-&lt;br /&gt;
|7.4-7.6&lt;br /&gt;
|Green&lt;br /&gt;
|pH Ideal&lt;br /&gt;
|-&lt;br /&gt;
|7.6-7.8&lt;br /&gt;
|Yellow&lt;br /&gt;
|pH High&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 7.8&lt;br /&gt;
|Red&lt;br /&gt;
|Scaling Water (See Note)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: Ideal pH is between 7.4 and 7.6.  A pH between 7.2 and 7.8 is generally acceptable (though possibly too low or too high).  A pH below 7.2 or above 7.8 may be problematic; verify by calculating the Langelier Saturation Index (LSI).&lt;br /&gt;
&lt;br /&gt;
=== ORP ===&lt;br /&gt;
&lt;br /&gt;
Shows the sampled water oxidation reduction potential (ORP) per a [[Chemtrol Pool Controller]] measurement (via RS-485/Ethernet link).&lt;br /&gt;
&lt;br /&gt;
== Graphs ==&lt;br /&gt;
&lt;br /&gt;
=== ORP ===&lt;br /&gt;
&lt;br /&gt;
[[File:ORP Graph Example.png|frame|An example of an ORP graph.]]&lt;br /&gt;
&lt;br /&gt;
The ORP graph shows the ORP measurement over time.  The graph shown contains two days worth of history.  Certain events, marked by numbers, can be identified:&lt;br /&gt;
&lt;br /&gt;
# A valley indicates a ORP trend direction change.  This typically occurs when chlorine is added to the pool.&lt;br /&gt;
# Overshoot and leveling-off is common overnight, as a lack of UV (and to some extent, pool occupants) prevents the rapid breakdown of chlorine in the pool water.&lt;br /&gt;
# Two events are identified in this marker.  First, the gradual drop in ORP as the sun hits the pool (starting at about 7:30 am).  Then, like in #1, a rise in ORP as chlorine is added to the pool.  Overshoot is much lower in this instance, as the pool is occupied and mid-day sunshine contributes to rapid chlorine breakdown.&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Systems_Dashboard&amp;diff=1778</id>
		<title>Pool Systems Dashboard</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Systems_Dashboard&amp;diff=1778"/>
		<updated>2025-06-30T18:42:32Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: /* LCD Monitor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The dashboard provides a visual interface for the [[Pool Systems Automation]].&lt;br /&gt;
&lt;br /&gt;
== System ==&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
&lt;br /&gt;
The hardware is responsible for data collection and display of the dashboard.  It is located on the south wall of the pump house.&lt;br /&gt;
&lt;br /&gt;
==== Raspberry Pi ====&lt;br /&gt;
&lt;br /&gt;
The dashboard presently runs on a [https://www.raspberrypi.com/products/raspberry-pi-5/ Raspberry Pi 5] (4 GB).  The Pi hardware was upgraded in 2025; previously it ran on a [https://www.raspberrypi.org/products/raspberry-pi-3-model-b/ Raspberry Pi 3 Model B] V1.2.&lt;br /&gt;
&lt;br /&gt;
The Pi is powered via a modified USB-C cable, connected to a Mean Well DDR-15G-5.  Note that previously, a a micro USB cable was used for the Pi 3B.  This device drops the 12 V chassis supply down to 5 V (for the Pi) and is capable of producing 15 W (3 A).  This exceeds the 2.5 A requirement cited for the Pi.  The internal WiFi radio is NOT used; instead, network connectivity is provided by Ethernet (to the Lantronix PremierWave XN).&lt;br /&gt;
&lt;br /&gt;
Communication with the [[Pool Systems Automation#Programmable Logic Controller|Programmable Logic Controller]] and [[Pool Boiler Temperature Controller|Temperature Controller]] requires a functional WiFi device network.&lt;br /&gt;
&lt;br /&gt;
==== Lantronix PremierWave XN ====&lt;br /&gt;
&lt;br /&gt;
The Lantronix PremierWave XN in the chassis with the Raspberry Pi has multiple purposes:&lt;br /&gt;
&lt;br /&gt;
* To provide serial-to-IP conversion for the RS-485 port on the [[Chemtrol Pool Controller]].&lt;br /&gt;
* To provide a link to the WiFi device network.&lt;br /&gt;
* To provide an Ethernet port, bridging/routing WiFi to the connected device.&lt;br /&gt;
&lt;br /&gt;
==== BeagleBone Black ====&lt;br /&gt;
&lt;br /&gt;
In the early trials, a [https://beagleboard.org/black BeagleBone Black] board was used.  Unfortunately, it had two significant limitations:&lt;br /&gt;
&lt;br /&gt;
* A lack of 1080p (or better) monitor support.  The proved problematic, as the HP Compaq LA2405x has a 1920x1200 native resolution.  The pixel clock on the CPU is limited to 126.5 MHz.  1920x1080x60 requires a pixel clock of 173 MHz; clearly 1920x1200 requires an even higher frequency pixel clock.  This was discussed with one of the main developers [https://forum.beagleboard.org/t/1680x1050x60-resolution-via-hdmi/2692/2 here].&lt;br /&gt;
* A single-core CPU.  As it turns out, the dashboard software requires a lot of CPU time to render in a browser.  So much so that a single core simply couldn&#039;t keep up; render times exceeded 30 seconds as I recall.  By using a CPU with multiple cores, the multiple threads of work can be spread out and processed in parallel.&lt;br /&gt;
&lt;br /&gt;
Both limitations aside, the BeagleBone Black is a fantastic piece of hardware, it just wasn&#039;t ideally suited for this project.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
&lt;br /&gt;
All software operates on [https://www.raspberrypi.org/software/operating-systems/ Raspberry Pi OS] (the &amp;quot;Lite&amp;quot; distribution), which is based on Debian GNU/Linux.&lt;br /&gt;
&lt;br /&gt;
==== InfluxDB ====&lt;br /&gt;
&lt;br /&gt;
[https://www.influxdata.com/products/influxdb-overview/ InfluxDB] is a time series database, used to store data collected by [https://www.influxdata.com/time-series-platform/telegraf/ Telegraf].&lt;br /&gt;
&lt;br /&gt;
Previously, [https://www.influxdata.com/time-series-platform/chronograf/ Chronograf] was used to display the data in a visually useful way on the dashboard.  [https://www.influxdata.com/time-series-platform/kapacitor/ Kapacitor] was used to trigger actions based upon data values.&lt;br /&gt;
&lt;br /&gt;
==== Grafana ====&lt;br /&gt;
&lt;br /&gt;
In the Pi 5 refresh, the Chronograf/Kapacitor portion of the InfluxDB TICK stack were replaced with [https://grafana.com/ Grafana].  This seems to be the preferred direction for InfluxDB 3 onward.  Grafana offers far more DB (input) hooks than Chronograf.&lt;br /&gt;
&lt;br /&gt;
==== Node-RED ====&lt;br /&gt;
&lt;br /&gt;
[https://nodered.org/ Node-RED] is used to request and interpret data from the [[Chemtrol Pool Controller]] via its RS-485 interface (over Ethernet).&lt;br /&gt;
&lt;br /&gt;
=== LCD Monitor ===&lt;br /&gt;
&lt;br /&gt;
The monitor is an &amp;quot;old&amp;quot; HP Compaq LA2405x.  This was an older surplus unit, installed in 2021.  It is/was fully expected that this monitor may eventually fail due to the corrosive environment it&#039;s exposed to in the summer, along with a cold/damp/unconditioned environment in the winter.  That said, it&#039;s still going strong as of 2025.  Replacement is straightforward; screws accessible on the bottom side release it from the VESA wall mount.  Any monitor with HD or better resolution and an HDMI input should suffice.&lt;br /&gt;
&lt;br /&gt;
== Gauges ==&lt;br /&gt;
&lt;br /&gt;
Gauge measurements are averaged in both the PLC and dashboard software.  Gauges may take several seconds (or longer) to respond to significant changes in system conditions.&lt;br /&gt;
&lt;br /&gt;
=== Filter Tank Pressure ===&lt;br /&gt;
&lt;br /&gt;
[[File:Tank Pressure Gauge Example.png|frame|An example of a tank pressure gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the pressure in pounds per square inch (psi) for a [[Sand Filters|sand filter]] tank per the PLC [[Pool Systems Automation#Filter Tank Pressure|Filter Tank Pressure]] measurement (via WiFi link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(psi)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0-4&lt;br /&gt;
|Red&lt;br /&gt;
|Critically Low Pressure (Pump/Flow Issue)&lt;br /&gt;
|-&lt;br /&gt;
|4-8&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Pressure (Flow Issue) - Consider [[Cleaning the Strainer Basket]]&lt;br /&gt;
|-&lt;br /&gt;
|8-18&lt;br /&gt;
|Green&lt;br /&gt;
|Normal Operating Pressure&lt;br /&gt;
|-&lt;br /&gt;
|18+&lt;br /&gt;
|Yellow/Red&lt;br /&gt;
|[[Backwashing|Backwash]] Recommended&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For consistent indication, the values above and dashboard visualization thresholds should always align with those defined within the [[Pool Systems Automation#Filter Tank Pressure|PLC thresholds]].&lt;br /&gt;
&lt;br /&gt;
Tank pressure is lowest when the [[Cleaning the Strainer Basket|strainer basket is clean]] and the sand filters have been recently [[Backwashing|backwashed]].  If pump outflow is restricted enough (in an effort to [[Pool Main Pump#Flow Rate|maintain proper flow]], it is possible for pressure to dip into the &amp;quot;Low Pressure&amp;quot; range.  This is not necessarily a cause for any concern.&lt;br /&gt;
&lt;br /&gt;
If the associated sensor is in a fault state (the sensor has failed, there is a wiring/fuse fault or the connector is unplugged), the gauge will show a value of 0.0.  A fault state is indicated by the PLC and the stack light.  If the gauge is not visible (the block is blank), a communication error with the PLC has occurred or a software issue is present on the dashboard PC.  Consult the system administrator.&lt;br /&gt;
&lt;br /&gt;
=== Surge Tank Level ===&lt;br /&gt;
&lt;br /&gt;
[[File:Surge Tank Depth Gauge Example.png|frame|An example of the surge tank level (depth) gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the level (depth) in inches for the surge tank per the PLC [[Pool Systems Automation#Surge Tank Level|Surge Tank Level]] measurement (via WiFi link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(in)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 16&lt;br /&gt;
|Red&lt;br /&gt;
|Critical Level&lt;br /&gt;
|-&lt;br /&gt;
|16-46&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Level (Auto-Fill Threshold)&lt;br /&gt;
|-&lt;br /&gt;
|46-60&lt;br /&gt;
|Green&lt;br /&gt;
|Nominal Level (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|60-76&lt;br /&gt;
|Blue&lt;br /&gt;
|Excess Level&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 76&lt;br /&gt;
|Red&lt;br /&gt;
|Overflow Level&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:  The &amp;quot;Nominal Level&amp;quot; of the surge tank is subject to future revision.  At this time, lacking a proper drain modulating valve, it is not possible to provide &amp;quot;surge&amp;quot; capacity (keep the tank level lowered during periods of high gutter flow).  As a result, some portion of the &amp;quot;Nominal Level&amp;quot; and &amp;quot;Excess Level&amp;quot; is expected when the pool level is high and/or there is a large amount of activity in the pool.  Ideally, the surge tank should usually remain below the gutter inlet level.&lt;br /&gt;
&lt;br /&gt;
When the &amp;quot;Critical Level&amp;quot; threshold is met, this may result in pump shutdown (per the PLC) to prevent pulling air into the pump.  The surge tank water level is insufficient to maintain operation.  When enabled, auto-fill begins at the upper end of the &amp;quot;Low Level&amp;quot; threshold and ends when the upper end of the &amp;quot;Nominal Level&amp;quot; is met.  A large amount of surge tank level hysteresis is needed when an actual pool level measurement is lacking.&lt;br /&gt;
&lt;br /&gt;
The tank nears overflow at the &amp;quot;Overflow Level&amp;quot; threshold.  No specific action is taken by the PLC at this point.&lt;br /&gt;
&lt;br /&gt;
=== Out Flow ===&lt;br /&gt;
&lt;br /&gt;
[[File:Out Flow Gauge Example.png|frame|An example of the out flow rate gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the out flow rate in gallons per minute (GPM).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 490&lt;br /&gt;
|Red&lt;br /&gt;
|Very Low Flow&lt;br /&gt;
|-&lt;br /&gt;
|490-570&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Flow (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|570-670&lt;br /&gt;
|Green&lt;br /&gt;
|Optimal Flow&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 670&lt;br /&gt;
|Yellow&lt;br /&gt;
|High Flow&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A target flow rate of 600 GPM has been established for manual adjustment.  This flow rate:&lt;br /&gt;
&lt;br /&gt;
* Meets the minimum pool turnover rate of 4 times per day (every 6 hours) for a 203,500 gallon pool.&lt;br /&gt;
* Is within some margin of the maximum flow rate set by the sand filters (140 GPM x 4 = 580 GPM).&lt;br /&gt;
&lt;br /&gt;
To prevent [[Sand Filters#Channeling|channeling]] in the sand filters, an upper bound of 670 GPM has been set (somewhat arbitrarily).  The operator should try to keep as close to 600 GPM operation as possible (without dipping below 570 GPM).&lt;br /&gt;
&lt;br /&gt;
=== Inlet Temperature ===&lt;br /&gt;
&lt;br /&gt;
[[File:Inlet Temperature Gauge Example.png|frame|An example of the inlet temperature gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the inlet temperature in degrees Fahrenheit (&amp;amp;deg;F) per the temperature controller measurement (via WiFi link).  This temperature is measured directly after the filter tanks, prior to the boiler loop (refer to the [[Process Flow Diagram]]).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 79&lt;br /&gt;
|Blue&lt;br /&gt;
|Low Temperature (Temperature Controller Alarm)&lt;br /&gt;
|-&lt;br /&gt;
|79-81&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Temperature (Outside of Controlled Bounds)&lt;br /&gt;
|-&lt;br /&gt;
|81+&lt;br /&gt;
|Green&lt;br /&gt;
|Normal Temperature&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The boiler is nominally set to 82 &amp;amp;deg;F.  Controller hysteresis keeps the temperature to within &amp;amp;plusmn;1 &amp;amp;deg;F or less.  The temperature controller enters an &amp;quot;alarm&amp;quot; state indicating that the boiler may be in a fault state once the temperature is below 79 &amp;amp;deg;F.  During hot summer days, temperatures of 82 &amp;amp;deg;F to 87 &amp;amp;deg;F are expected and normal.&lt;br /&gt;
&lt;br /&gt;
=== pH ===&lt;br /&gt;
&lt;br /&gt;
[[File:pH Gauge Example.png|frame|An example of the pH gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the sampled water pH per a [[Chemtrol Pool Controller]] measurement (via RS-485/Ethernet link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 7.2&lt;br /&gt;
|Red&lt;br /&gt;
|Corrosive Water (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|7.2-7.4&lt;br /&gt;
|Yellow&lt;br /&gt;
|pH Low&lt;br /&gt;
|-&lt;br /&gt;
|7.4-7.6&lt;br /&gt;
|Green&lt;br /&gt;
|pH Ideal&lt;br /&gt;
|-&lt;br /&gt;
|7.6-7.8&lt;br /&gt;
|Yellow&lt;br /&gt;
|pH High&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 7.8&lt;br /&gt;
|Red&lt;br /&gt;
|Scaling Water (See Note)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: Ideal pH is between 7.4 and 7.6.  A pH between 7.2 and 7.8 is generally acceptable (though possibly too low or too high).  A pH below 7.2 or above 7.8 may be problematic; verify by calculating the Langelier Saturation Index (LSI).&lt;br /&gt;
&lt;br /&gt;
=== ORP ===&lt;br /&gt;
&lt;br /&gt;
[[File:ORP Gauge Example.png|frame|An example of the ORP gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the sampled water oxidation reduction potential (ORP) per a [[Chemtrol Pool Controller]] measurement (via RS-485/Ethernet link).&lt;br /&gt;
&lt;br /&gt;
== Graphs ==&lt;br /&gt;
&lt;br /&gt;
=== ORP ===&lt;br /&gt;
&lt;br /&gt;
[[File:ORP Graph Example.png|frame|An example of an ORP graph.]]&lt;br /&gt;
&lt;br /&gt;
The ORP graph shows the ORP measurement over time.  The graph shown contains two days worth of history.  Certain events, marked by numbers, can be identified:&lt;br /&gt;
&lt;br /&gt;
# A valley indicates a ORP trend direction change.  This typically occurs when chlorine is added to the pool.&lt;br /&gt;
# Overshoot and leveling-off is common overnight, as a lack of UV (and to some extent, pool occupants) prevents the rapid breakdown of chlorine in the pool water.&lt;br /&gt;
# Two events are identified in this marker.  First, the gradual drop in ORP as the sun hits the pool (starting at about 7:30 am).  Then, like in #1, a rise in ORP as chlorine is added to the pool.  Overshoot is much lower in this instance, as the pool is occupied and mid-day sunshine contributes to rapid chlorine breakdown.&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Systems_Dashboard&amp;diff=1777</id>
		<title>Pool Systems Dashboard</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Systems_Dashboard&amp;diff=1777"/>
		<updated>2025-06-30T18:40:51Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: /* Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The dashboard provides a visual interface for the [[Pool Systems Automation]].&lt;br /&gt;
&lt;br /&gt;
== System ==&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
&lt;br /&gt;
The hardware is responsible for data collection and display of the dashboard.  It is located on the south wall of the pump house.&lt;br /&gt;
&lt;br /&gt;
==== Raspberry Pi ====&lt;br /&gt;
&lt;br /&gt;
The dashboard presently runs on a [https://www.raspberrypi.com/products/raspberry-pi-5/ Raspberry Pi 5] (4 GB).  The Pi hardware was upgraded in 2025; previously it ran on a [https://www.raspberrypi.org/products/raspberry-pi-3-model-b/ Raspberry Pi 3 Model B] V1.2.&lt;br /&gt;
&lt;br /&gt;
The Pi is powered via a modified USB-C cable, connected to a Mean Well DDR-15G-5.  Note that previously, a a micro USB cable was used for the Pi 3B.  This device drops the 12 V chassis supply down to 5 V (for the Pi) and is capable of producing 15 W (3 A).  This exceeds the 2.5 A requirement cited for the Pi.  The internal WiFi radio is NOT used; instead, network connectivity is provided by Ethernet (to the Lantronix PremierWave XN).&lt;br /&gt;
&lt;br /&gt;
Communication with the [[Pool Systems Automation#Programmable Logic Controller|Programmable Logic Controller]] and [[Pool Boiler Temperature Controller|Temperature Controller]] requires a functional WiFi device network.&lt;br /&gt;
&lt;br /&gt;
==== Lantronix PremierWave XN ====&lt;br /&gt;
&lt;br /&gt;
The Lantronix PremierWave XN in the chassis with the Raspberry Pi has multiple purposes:&lt;br /&gt;
&lt;br /&gt;
* To provide serial-to-IP conversion for the RS-485 port on the [[Chemtrol Pool Controller]].&lt;br /&gt;
* To provide a link to the WiFi device network.&lt;br /&gt;
* To provide an Ethernet port, bridging/routing WiFi to the connected device.&lt;br /&gt;
&lt;br /&gt;
==== BeagleBone Black ====&lt;br /&gt;
&lt;br /&gt;
In the early trials, a [https://beagleboard.org/black BeagleBone Black] board was used.  Unfortunately, it had two significant limitations:&lt;br /&gt;
&lt;br /&gt;
* A lack of 1080p (or better) monitor support.  The proved problematic, as the HP Compaq LA2405x has a 1920x1200 native resolution.  The pixel clock on the CPU is limited to 126.5 MHz.  1920x1080x60 requires a pixel clock of 173 MHz; clearly 1920x1200 requires an even higher frequency pixel clock.  This was discussed with one of the main developers [https://forum.beagleboard.org/t/1680x1050x60-resolution-via-hdmi/2692/2 here].&lt;br /&gt;
* A single-core CPU.  As it turns out, the dashboard software requires a lot of CPU time to render in a browser.  So much so that a single core simply couldn&#039;t keep up; render times exceeded 30 seconds as I recall.  By using a CPU with multiple cores, the multiple threads of work can be spread out and processed in parallel.&lt;br /&gt;
&lt;br /&gt;
Both limitations aside, the BeagleBone Black is a fantastic piece of hardware, it just wasn&#039;t ideally suited for this project.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
&lt;br /&gt;
All software operates on [https://www.raspberrypi.org/software/operating-systems/ Raspberry Pi OS] (the &amp;quot;Lite&amp;quot; distribution), which is based on Debian GNU/Linux.&lt;br /&gt;
&lt;br /&gt;
==== InfluxDB ====&lt;br /&gt;
&lt;br /&gt;
[https://www.influxdata.com/products/influxdb-overview/ InfluxDB] is a time series database, used to store data collected by [https://www.influxdata.com/time-series-platform/telegraf/ Telegraf].&lt;br /&gt;
&lt;br /&gt;
Previously, [https://www.influxdata.com/time-series-platform/chronograf/ Chronograf] was used to display the data in a visually useful way on the dashboard.  [https://www.influxdata.com/time-series-platform/kapacitor/ Kapacitor] was used to trigger actions based upon data values.&lt;br /&gt;
&lt;br /&gt;
==== Grafana ====&lt;br /&gt;
&lt;br /&gt;
In the Pi 5 refresh, the Chronograf/Kapacitor portion of the InfluxDB TICK stack were replaced with [https://grafana.com/ Grafana].  This seems to be the preferred direction for InfluxDB 3 onward.  Grafana offers far more DB (input) hooks than Chronograf.&lt;br /&gt;
&lt;br /&gt;
==== Node-RED ====&lt;br /&gt;
&lt;br /&gt;
[https://nodered.org/ Node-RED] is used to request and interpret data from the [[Chemtrol Pool Controller]] via its RS-485 interface (over Ethernet).&lt;br /&gt;
&lt;br /&gt;
=== LCD Monitor ===&lt;br /&gt;
&lt;br /&gt;
As of 2021, the monitor is an &amp;quot;old&amp;quot; HP Compaq LA2405x.  This was an older surplus unit, chosen for its scrap bin destiny.  It&#039;s fully expected that this monitor may eventually fail due to the corrosive environment it&#039;s exposed to in the summer, along with a cold/damp/unconditioned environment in the winter.  Replacement is straightforward; screws accessible on the bottom side release it from the VESA wall mount.  Any monitor with HD or better resolution and an HDMI input should suffice.&lt;br /&gt;
&lt;br /&gt;
== Gauges ==&lt;br /&gt;
&lt;br /&gt;
Gauge measurements are averaged in both the PLC and dashboard software.  Gauges may take several seconds (or longer) to respond to significant changes in system conditions.&lt;br /&gt;
&lt;br /&gt;
=== Filter Tank Pressure ===&lt;br /&gt;
&lt;br /&gt;
[[File:Tank Pressure Gauge Example.png|frame|An example of a tank pressure gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the pressure in pounds per square inch (psi) for a [[Sand Filters|sand filter]] tank per the PLC [[Pool Systems Automation#Filter Tank Pressure|Filter Tank Pressure]] measurement (via WiFi link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(psi)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0-4&lt;br /&gt;
|Red&lt;br /&gt;
|Critically Low Pressure (Pump/Flow Issue)&lt;br /&gt;
|-&lt;br /&gt;
|4-8&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Pressure (Flow Issue) - Consider [[Cleaning the Strainer Basket]]&lt;br /&gt;
|-&lt;br /&gt;
|8-18&lt;br /&gt;
|Green&lt;br /&gt;
|Normal Operating Pressure&lt;br /&gt;
|-&lt;br /&gt;
|18+&lt;br /&gt;
|Yellow/Red&lt;br /&gt;
|[[Backwashing|Backwash]] Recommended&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For consistent indication, the values above and dashboard visualization thresholds should always align with those defined within the [[Pool Systems Automation#Filter Tank Pressure|PLC thresholds]].&lt;br /&gt;
&lt;br /&gt;
Tank pressure is lowest when the [[Cleaning the Strainer Basket|strainer basket is clean]] and the sand filters have been recently [[Backwashing|backwashed]].  If pump outflow is restricted enough (in an effort to [[Pool Main Pump#Flow Rate|maintain proper flow]], it is possible for pressure to dip into the &amp;quot;Low Pressure&amp;quot; range.  This is not necessarily a cause for any concern.&lt;br /&gt;
&lt;br /&gt;
If the associated sensor is in a fault state (the sensor has failed, there is a wiring/fuse fault or the connector is unplugged), the gauge will show a value of 0.0.  A fault state is indicated by the PLC and the stack light.  If the gauge is not visible (the block is blank), a communication error with the PLC has occurred or a software issue is present on the dashboard PC.  Consult the system administrator.&lt;br /&gt;
&lt;br /&gt;
=== Surge Tank Level ===&lt;br /&gt;
&lt;br /&gt;
[[File:Surge Tank Depth Gauge Example.png|frame|An example of the surge tank level (depth) gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the level (depth) in inches for the surge tank per the PLC [[Pool Systems Automation#Surge Tank Level|Surge Tank Level]] measurement (via WiFi link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(in)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 16&lt;br /&gt;
|Red&lt;br /&gt;
|Critical Level&lt;br /&gt;
|-&lt;br /&gt;
|16-46&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Level (Auto-Fill Threshold)&lt;br /&gt;
|-&lt;br /&gt;
|46-60&lt;br /&gt;
|Green&lt;br /&gt;
|Nominal Level (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|60-76&lt;br /&gt;
|Blue&lt;br /&gt;
|Excess Level&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 76&lt;br /&gt;
|Red&lt;br /&gt;
|Overflow Level&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:  The &amp;quot;Nominal Level&amp;quot; of the surge tank is subject to future revision.  At this time, lacking a proper drain modulating valve, it is not possible to provide &amp;quot;surge&amp;quot; capacity (keep the tank level lowered during periods of high gutter flow).  As a result, some portion of the &amp;quot;Nominal Level&amp;quot; and &amp;quot;Excess Level&amp;quot; is expected when the pool level is high and/or there is a large amount of activity in the pool.  Ideally, the surge tank should usually remain below the gutter inlet level.&lt;br /&gt;
&lt;br /&gt;
When the &amp;quot;Critical Level&amp;quot; threshold is met, this may result in pump shutdown (per the PLC) to prevent pulling air into the pump.  The surge tank water level is insufficient to maintain operation.  When enabled, auto-fill begins at the upper end of the &amp;quot;Low Level&amp;quot; threshold and ends when the upper end of the &amp;quot;Nominal Level&amp;quot; is met.  A large amount of surge tank level hysteresis is needed when an actual pool level measurement is lacking.&lt;br /&gt;
&lt;br /&gt;
The tank nears overflow at the &amp;quot;Overflow Level&amp;quot; threshold.  No specific action is taken by the PLC at this point.&lt;br /&gt;
&lt;br /&gt;
=== Out Flow ===&lt;br /&gt;
&lt;br /&gt;
[[File:Out Flow Gauge Example.png|frame|An example of the out flow rate gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the out flow rate in gallons per minute (GPM).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 490&lt;br /&gt;
|Red&lt;br /&gt;
|Very Low Flow&lt;br /&gt;
|-&lt;br /&gt;
|490-570&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Flow (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|570-670&lt;br /&gt;
|Green&lt;br /&gt;
|Optimal Flow&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 670&lt;br /&gt;
|Yellow&lt;br /&gt;
|High Flow&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A target flow rate of 600 GPM has been established for manual adjustment.  This flow rate:&lt;br /&gt;
&lt;br /&gt;
* Meets the minimum pool turnover rate of 4 times per day (every 6 hours) for a 203,500 gallon pool.&lt;br /&gt;
* Is within some margin of the maximum flow rate set by the sand filters (140 GPM x 4 = 580 GPM).&lt;br /&gt;
&lt;br /&gt;
To prevent [[Sand Filters#Channeling|channeling]] in the sand filters, an upper bound of 670 GPM has been set (somewhat arbitrarily).  The operator should try to keep as close to 600 GPM operation as possible (without dipping below 570 GPM).&lt;br /&gt;
&lt;br /&gt;
=== Inlet Temperature ===&lt;br /&gt;
&lt;br /&gt;
[[File:Inlet Temperature Gauge Example.png|frame|An example of the inlet temperature gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the inlet temperature in degrees Fahrenheit (&amp;amp;deg;F) per the temperature controller measurement (via WiFi link).  This temperature is measured directly after the filter tanks, prior to the boiler loop (refer to the [[Process Flow Diagram]]).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 79&lt;br /&gt;
|Blue&lt;br /&gt;
|Low Temperature (Temperature Controller Alarm)&lt;br /&gt;
|-&lt;br /&gt;
|79-81&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Temperature (Outside of Controlled Bounds)&lt;br /&gt;
|-&lt;br /&gt;
|81+&lt;br /&gt;
|Green&lt;br /&gt;
|Normal Temperature&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The boiler is nominally set to 82 &amp;amp;deg;F.  Controller hysteresis keeps the temperature to within &amp;amp;plusmn;1 &amp;amp;deg;F or less.  The temperature controller enters an &amp;quot;alarm&amp;quot; state indicating that the boiler may be in a fault state once the temperature is below 79 &amp;amp;deg;F.  During hot summer days, temperatures of 82 &amp;amp;deg;F to 87 &amp;amp;deg;F are expected and normal.&lt;br /&gt;
&lt;br /&gt;
=== pH ===&lt;br /&gt;
&lt;br /&gt;
[[File:pH Gauge Example.png|frame|An example of the pH gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the sampled water pH per a [[Chemtrol Pool Controller]] measurement (via RS-485/Ethernet link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 7.2&lt;br /&gt;
|Red&lt;br /&gt;
|Corrosive Water (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|7.2-7.4&lt;br /&gt;
|Yellow&lt;br /&gt;
|pH Low&lt;br /&gt;
|-&lt;br /&gt;
|7.4-7.6&lt;br /&gt;
|Green&lt;br /&gt;
|pH Ideal&lt;br /&gt;
|-&lt;br /&gt;
|7.6-7.8&lt;br /&gt;
|Yellow&lt;br /&gt;
|pH High&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 7.8&lt;br /&gt;
|Red&lt;br /&gt;
|Scaling Water (See Note)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: Ideal pH is between 7.4 and 7.6.  A pH between 7.2 and 7.8 is generally acceptable (though possibly too low or too high).  A pH below 7.2 or above 7.8 may be problematic; verify by calculating the Langelier Saturation Index (LSI).&lt;br /&gt;
&lt;br /&gt;
=== ORP ===&lt;br /&gt;
&lt;br /&gt;
[[File:ORP Gauge Example.png|frame|An example of the ORP gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the sampled water oxidation reduction potential (ORP) per a [[Chemtrol Pool Controller]] measurement (via RS-485/Ethernet link).&lt;br /&gt;
&lt;br /&gt;
== Graphs ==&lt;br /&gt;
&lt;br /&gt;
=== ORP ===&lt;br /&gt;
&lt;br /&gt;
[[File:ORP Graph Example.png|frame|An example of an ORP graph.]]&lt;br /&gt;
&lt;br /&gt;
The ORP graph shows the ORP measurement over time.  The graph shown contains two days worth of history.  Certain events, marked by numbers, can be identified:&lt;br /&gt;
&lt;br /&gt;
# A valley indicates a ORP trend direction change.  This typically occurs when chlorine is added to the pool.&lt;br /&gt;
# Overshoot and leveling-off is common overnight, as a lack of UV (and to some extent, pool occupants) prevents the rapid breakdown of chlorine in the pool water.&lt;br /&gt;
# Two events are identified in this marker.  First, the gradual drop in ORP as the sun hits the pool (starting at about 7:30 am).  Then, like in #1, a rise in ORP as chlorine is added to the pool.  Overshoot is much lower in this instance, as the pool is occupied and mid-day sunshine contributes to rapid chlorine breakdown.&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Systems_Dashboard&amp;diff=1776</id>
		<title>Pool Systems Dashboard</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Systems_Dashboard&amp;diff=1776"/>
		<updated>2025-06-30T18:40:05Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: /* Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The dashboard provides a visual interface for the [[Pool Systems Automation]].&lt;br /&gt;
&lt;br /&gt;
== System ==&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
&lt;br /&gt;
The hardware is responsible for data collection and display of the dashboard.  It is located on the south wall of the pump house.&lt;br /&gt;
&lt;br /&gt;
==== Raspberry Pi ====&lt;br /&gt;
&lt;br /&gt;
The dashboard presently runs on a [https://www.raspberrypi.com/products/raspberry-pi-5/ Raspberry Pi 5] (4 GB).  The Pi hardware was upgraded in 2025; previously it ran on a [https://www.raspberrypi.org/products/raspberry-pi-3-model-b/ Raspberry Pi 3 Model B] V1.2.&lt;br /&gt;
&lt;br /&gt;
The Pi is powered via a modified USB-C cable, connected to a Mean Well DDR-15G-5.  Note that previously, a a micro USB cable was used for the Pi 3B.  This device drops the 12 V chassis supply down to 5 V (for the Pi) and is capable of producing 15 W (3 A).  This exceeds the 2.5 A requirement cited for the Pi.  The internal WiFi radio is NOT used; instead, network connectivity is provided by Ethernet (to the Lantronix PremierWave XN).&lt;br /&gt;
&lt;br /&gt;
Communication with the [[Pool Systems Automation#Programmable Logic Controller|Programmable Logic Controller]] and [[Pool Boiler Temperature Controller|Temperature Controller]] requires a functional WiFi device network.&lt;br /&gt;
&lt;br /&gt;
==== Lantronix PremierWave XN ====&lt;br /&gt;
&lt;br /&gt;
The Lantronix PremierWave XN in the chassis with the Raspberry Pi has multiple purposes:&lt;br /&gt;
&lt;br /&gt;
* To provide serial-to-IP conversion for the RS-485 port on the [[Chemtrol Pool Controller]].&lt;br /&gt;
* To provide a link to the WiFi device network.&lt;br /&gt;
* To provide an Ethernet port, bridging/routing WiFi to the connected device.&lt;br /&gt;
&lt;br /&gt;
==== BeagleBone Black ====&lt;br /&gt;
&lt;br /&gt;
In the early trials, a [https://beagleboard.org/black BeagleBone Black] board was used.  Unfortunately, it had two significant limitations:&lt;br /&gt;
&lt;br /&gt;
* A lack of 1080p (or better) monitor support.  The proved problematic, as the HP Compaq LA2405x has a 1920x1200 native resolution.  The pixel clock on the CPU is limited to 126.5 MHz.  1920x1080x60 requires a pixel clock of 173 MHz; clearly 1920x1200 requires an even higher frequency pixel clock.  This was discussed with one of the main developers [https://forum.beagleboard.org/t/1680x1050x60-resolution-via-hdmi/2692/2 here].&lt;br /&gt;
* A single-core CPU.  As it turns out, the dashboard software requires a lot of CPU time to render in a browser.  So much so that a single core simply couldn&#039;t keep up; render times exceeded 30 seconds as I recall.  By using a CPU with multiple cores, the multiple threads of work can be spread out and processed in parallel.&lt;br /&gt;
&lt;br /&gt;
Both limitations aside, the BeagleBone Black is a fantastic piece of hardware, it just wasn&#039;t ideally suited for this project.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
&lt;br /&gt;
All software operates on [https://www.raspberrypi.org/software/operating-systems/ Raspberry Pi OS] (the &amp;quot;Lite&amp;quot; distribution), which is based on Debian GNU/Linux.&lt;br /&gt;
&lt;br /&gt;
==== InfluxDB ====&lt;br /&gt;
&lt;br /&gt;
[https://www.influxdata.com/products/influxdb-overview/ InfluxDB] is a time series database, used to store data collected by [https://www.influxdata.com/time-series-platform/telegraf/ Telegraf].&lt;br /&gt;
&lt;br /&gt;
Previously, [https://www.influxdata.com/time-series-platform/chronograf/ Chronograf] was used to display the data in a visually useful way on the dashboard.  [https://www.influxdata.com/time-series-platform/kapacitor/ Kapacitor] was used to trigger actions based upon data values.&lt;br /&gt;
&lt;br /&gt;
==== Grafana ====&lt;br /&gt;
&lt;br /&gt;
In the Pi 5 refresh, the Chronograf/Kapacitor portion of the InfluxdB TICK stack were replaced with Grafana.  This seems to be the preferred direction for InfluxDB 3 onward.  Grafana also offers far more DB (input) hooks than Chronograf, so it seems to be a good choice going forward.&lt;br /&gt;
&lt;br /&gt;
==== Node-RED ====&lt;br /&gt;
&lt;br /&gt;
[https://nodered.org/ Node-RED] is used to request and interpret data from the [[Chemtrol Pool Controller]] via its RS-485 interface (over Ethernet).&lt;br /&gt;
&lt;br /&gt;
=== LCD Monitor ===&lt;br /&gt;
&lt;br /&gt;
As of 2021, the monitor is an &amp;quot;old&amp;quot; HP Compaq LA2405x.  This was an older surplus unit, chosen for its scrap bin destiny.  It&#039;s fully expected that this monitor may eventually fail due to the corrosive environment it&#039;s exposed to in the summer, along with a cold/damp/unconditioned environment in the winter.  Replacement is straightforward; screws accessible on the bottom side release it from the VESA wall mount.  Any monitor with HD or better resolution and an HDMI input should suffice.&lt;br /&gt;
&lt;br /&gt;
== Gauges ==&lt;br /&gt;
&lt;br /&gt;
Gauge measurements are averaged in both the PLC and dashboard software.  Gauges may take several seconds (or longer) to respond to significant changes in system conditions.&lt;br /&gt;
&lt;br /&gt;
=== Filter Tank Pressure ===&lt;br /&gt;
&lt;br /&gt;
[[File:Tank Pressure Gauge Example.png|frame|An example of a tank pressure gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the pressure in pounds per square inch (psi) for a [[Sand Filters|sand filter]] tank per the PLC [[Pool Systems Automation#Filter Tank Pressure|Filter Tank Pressure]] measurement (via WiFi link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(psi)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0-4&lt;br /&gt;
|Red&lt;br /&gt;
|Critically Low Pressure (Pump/Flow Issue)&lt;br /&gt;
|-&lt;br /&gt;
|4-8&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Pressure (Flow Issue) - Consider [[Cleaning the Strainer Basket]]&lt;br /&gt;
|-&lt;br /&gt;
|8-18&lt;br /&gt;
|Green&lt;br /&gt;
|Normal Operating Pressure&lt;br /&gt;
|-&lt;br /&gt;
|18+&lt;br /&gt;
|Yellow/Red&lt;br /&gt;
|[[Backwashing|Backwash]] Recommended&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For consistent indication, the values above and dashboard visualization thresholds should always align with those defined within the [[Pool Systems Automation#Filter Tank Pressure|PLC thresholds]].&lt;br /&gt;
&lt;br /&gt;
Tank pressure is lowest when the [[Cleaning the Strainer Basket|strainer basket is clean]] and the sand filters have been recently [[Backwashing|backwashed]].  If pump outflow is restricted enough (in an effort to [[Pool Main Pump#Flow Rate|maintain proper flow]], it is possible for pressure to dip into the &amp;quot;Low Pressure&amp;quot; range.  This is not necessarily a cause for any concern.&lt;br /&gt;
&lt;br /&gt;
If the associated sensor is in a fault state (the sensor has failed, there is a wiring/fuse fault or the connector is unplugged), the gauge will show a value of 0.0.  A fault state is indicated by the PLC and the stack light.  If the gauge is not visible (the block is blank), a communication error with the PLC has occurred or a software issue is present on the dashboard PC.  Consult the system administrator.&lt;br /&gt;
&lt;br /&gt;
=== Surge Tank Level ===&lt;br /&gt;
&lt;br /&gt;
[[File:Surge Tank Depth Gauge Example.png|frame|An example of the surge tank level (depth) gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the level (depth) in inches for the surge tank per the PLC [[Pool Systems Automation#Surge Tank Level|Surge Tank Level]] measurement (via WiFi link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(in)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 16&lt;br /&gt;
|Red&lt;br /&gt;
|Critical Level&lt;br /&gt;
|-&lt;br /&gt;
|16-46&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Level (Auto-Fill Threshold)&lt;br /&gt;
|-&lt;br /&gt;
|46-60&lt;br /&gt;
|Green&lt;br /&gt;
|Nominal Level (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|60-76&lt;br /&gt;
|Blue&lt;br /&gt;
|Excess Level&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 76&lt;br /&gt;
|Red&lt;br /&gt;
|Overflow Level&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:  The &amp;quot;Nominal Level&amp;quot; of the surge tank is subject to future revision.  At this time, lacking a proper drain modulating valve, it is not possible to provide &amp;quot;surge&amp;quot; capacity (keep the tank level lowered during periods of high gutter flow).  As a result, some portion of the &amp;quot;Nominal Level&amp;quot; and &amp;quot;Excess Level&amp;quot; is expected when the pool level is high and/or there is a large amount of activity in the pool.  Ideally, the surge tank should usually remain below the gutter inlet level.&lt;br /&gt;
&lt;br /&gt;
When the &amp;quot;Critical Level&amp;quot; threshold is met, this may result in pump shutdown (per the PLC) to prevent pulling air into the pump.  The surge tank water level is insufficient to maintain operation.  When enabled, auto-fill begins at the upper end of the &amp;quot;Low Level&amp;quot; threshold and ends when the upper end of the &amp;quot;Nominal Level&amp;quot; is met.  A large amount of surge tank level hysteresis is needed when an actual pool level measurement is lacking.&lt;br /&gt;
&lt;br /&gt;
The tank nears overflow at the &amp;quot;Overflow Level&amp;quot; threshold.  No specific action is taken by the PLC at this point.&lt;br /&gt;
&lt;br /&gt;
=== Out Flow ===&lt;br /&gt;
&lt;br /&gt;
[[File:Out Flow Gauge Example.png|frame|An example of the out flow rate gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the out flow rate in gallons per minute (GPM).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 490&lt;br /&gt;
|Red&lt;br /&gt;
|Very Low Flow&lt;br /&gt;
|-&lt;br /&gt;
|490-570&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Flow (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|570-670&lt;br /&gt;
|Green&lt;br /&gt;
|Optimal Flow&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 670&lt;br /&gt;
|Yellow&lt;br /&gt;
|High Flow&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A target flow rate of 600 GPM has been established for manual adjustment.  This flow rate:&lt;br /&gt;
&lt;br /&gt;
* Meets the minimum pool turnover rate of 4 times per day (every 6 hours) for a 203,500 gallon pool.&lt;br /&gt;
* Is within some margin of the maximum flow rate set by the sand filters (140 GPM x 4 = 580 GPM).&lt;br /&gt;
&lt;br /&gt;
To prevent [[Sand Filters#Channeling|channeling]] in the sand filters, an upper bound of 670 GPM has been set (somewhat arbitrarily).  The operator should try to keep as close to 600 GPM operation as possible (without dipping below 570 GPM).&lt;br /&gt;
&lt;br /&gt;
=== Inlet Temperature ===&lt;br /&gt;
&lt;br /&gt;
[[File:Inlet Temperature Gauge Example.png|frame|An example of the inlet temperature gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the inlet temperature in degrees Fahrenheit (&amp;amp;deg;F) per the temperature controller measurement (via WiFi link).  This temperature is measured directly after the filter tanks, prior to the boiler loop (refer to the [[Process Flow Diagram]]).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 79&lt;br /&gt;
|Blue&lt;br /&gt;
|Low Temperature (Temperature Controller Alarm)&lt;br /&gt;
|-&lt;br /&gt;
|79-81&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Temperature (Outside of Controlled Bounds)&lt;br /&gt;
|-&lt;br /&gt;
|81+&lt;br /&gt;
|Green&lt;br /&gt;
|Normal Temperature&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The boiler is nominally set to 82 &amp;amp;deg;F.  Controller hysteresis keeps the temperature to within &amp;amp;plusmn;1 &amp;amp;deg;F or less.  The temperature controller enters an &amp;quot;alarm&amp;quot; state indicating that the boiler may be in a fault state once the temperature is below 79 &amp;amp;deg;F.  During hot summer days, temperatures of 82 &amp;amp;deg;F to 87 &amp;amp;deg;F are expected and normal.&lt;br /&gt;
&lt;br /&gt;
=== pH ===&lt;br /&gt;
&lt;br /&gt;
[[File:pH Gauge Example.png|frame|An example of the pH gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the sampled water pH per a [[Chemtrol Pool Controller]] measurement (via RS-485/Ethernet link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 7.2&lt;br /&gt;
|Red&lt;br /&gt;
|Corrosive Water (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|7.2-7.4&lt;br /&gt;
|Yellow&lt;br /&gt;
|pH Low&lt;br /&gt;
|-&lt;br /&gt;
|7.4-7.6&lt;br /&gt;
|Green&lt;br /&gt;
|pH Ideal&lt;br /&gt;
|-&lt;br /&gt;
|7.6-7.8&lt;br /&gt;
|Yellow&lt;br /&gt;
|pH High&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 7.8&lt;br /&gt;
|Red&lt;br /&gt;
|Scaling Water (See Note)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: Ideal pH is between 7.4 and 7.6.  A pH between 7.2 and 7.8 is generally acceptable (though possibly too low or too high).  A pH below 7.2 or above 7.8 may be problematic; verify by calculating the Langelier Saturation Index (LSI).&lt;br /&gt;
&lt;br /&gt;
=== ORP ===&lt;br /&gt;
&lt;br /&gt;
[[File:ORP Gauge Example.png|frame|An example of the ORP gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the sampled water oxidation reduction potential (ORP) per a [[Chemtrol Pool Controller]] measurement (via RS-485/Ethernet link).&lt;br /&gt;
&lt;br /&gt;
== Graphs ==&lt;br /&gt;
&lt;br /&gt;
=== ORP ===&lt;br /&gt;
&lt;br /&gt;
[[File:ORP Graph Example.png|frame|An example of an ORP graph.]]&lt;br /&gt;
&lt;br /&gt;
The ORP graph shows the ORP measurement over time.  The graph shown contains two days worth of history.  Certain events, marked by numbers, can be identified:&lt;br /&gt;
&lt;br /&gt;
# A valley indicates a ORP trend direction change.  This typically occurs when chlorine is added to the pool.&lt;br /&gt;
# Overshoot and leveling-off is common overnight, as a lack of UV (and to some extent, pool occupants) prevents the rapid breakdown of chlorine in the pool water.&lt;br /&gt;
# Two events are identified in this marker.  First, the gradual drop in ORP as the sun hits the pool (starting at about 7:30 am).  Then, like in #1, a rise in ORP as chlorine is added to the pool.  Overshoot is much lower in this instance, as the pool is occupied and mid-day sunshine contributes to rapid chlorine breakdown.&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Systems_Dashboard&amp;diff=1775</id>
		<title>Pool Systems Dashboard</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Systems_Dashboard&amp;diff=1775"/>
		<updated>2025-06-30T18:36:03Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: /* Hardware */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The dashboard provides a visual interface for the [[Pool Systems Automation]].&lt;br /&gt;
&lt;br /&gt;
== System ==&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
&lt;br /&gt;
The hardware is responsible for data collection and display of the dashboard.  It is located on the south wall of the pump house.&lt;br /&gt;
&lt;br /&gt;
==== Raspberry Pi ====&lt;br /&gt;
&lt;br /&gt;
The dashboard presently runs on a [https://www.raspberrypi.com/products/raspberry-pi-5/ Raspberry Pi 5] (4 GB).  The Pi hardware was upgraded in 2025; previously it ran on a [https://www.raspberrypi.org/products/raspberry-pi-3-model-b/ Raspberry Pi 3 Model B] V1.2.&lt;br /&gt;
&lt;br /&gt;
The Pi is powered via a modified USB-C cable, connected to a Mean Well DDR-15G-5.  Note that previously, a a micro USB cable was used for the Pi 3B.  This device drops the 12 V chassis supply down to 5 V (for the Pi) and is capable of producing 15 W (3 A).  This exceeds the 2.5 A requirement cited for the Pi.  The internal WiFi radio is NOT used; instead, network connectivity is provided by Ethernet (to the Lantronix PremierWave XN).&lt;br /&gt;
&lt;br /&gt;
Communication with the [[Pool Systems Automation#Programmable Logic Controller|Programmable Logic Controller]] and [[Pool Boiler Temperature Controller|Temperature Controller]] requires a functional WiFi device network.&lt;br /&gt;
&lt;br /&gt;
==== Lantronix PremierWave XN ====&lt;br /&gt;
&lt;br /&gt;
The Lantronix PremierWave XN in the chassis with the Raspberry Pi has multiple purposes:&lt;br /&gt;
&lt;br /&gt;
* To provide serial-to-IP conversion for the RS-485 port on the [[Chemtrol Pool Controller]].&lt;br /&gt;
* To provide a link to the WiFi device network.&lt;br /&gt;
* To provide an Ethernet port, bridging/routing WiFi to the connected device.&lt;br /&gt;
&lt;br /&gt;
==== BeagleBone Black ====&lt;br /&gt;
&lt;br /&gt;
In the early trials, a [https://beagleboard.org/black BeagleBone Black] board was used.  Unfortunately, it had two significant limitations:&lt;br /&gt;
&lt;br /&gt;
* A lack of 1080p (or better) monitor support.  The proved problematic, as the HP Compaq LA2405x has a 1920x1200 native resolution.  The pixel clock on the CPU is limited to 126.5 MHz.  1920x1080x60 requires a pixel clock of 173 MHz; clearly 1920x1200 requires an even higher frequency pixel clock.  This was discussed with one of the main developers [https://forum.beagleboard.org/t/1680x1050x60-resolution-via-hdmi/2692/2 here].&lt;br /&gt;
* A single-core CPU.  As it turns out, the dashboard software requires a lot of CPU time to render in a browser.  So much so that a single core simply couldn&#039;t keep up; render times exceeded 30 seconds as I recall.  By using a CPU with multiple cores, the multiple threads of work can be spread out and processed in parallel.&lt;br /&gt;
&lt;br /&gt;
Both limitations aside, the BeagleBone Black is a fantastic piece of hardware, it just wasn&#039;t ideally suited for this project.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
&lt;br /&gt;
All software operates on [https://www.raspberrypi.org/software/operating-systems/ Raspberry Pi OS] (the &amp;quot;Desktop&amp;quot; distribution), which is based on Debian GNU/Linux.&lt;br /&gt;
&lt;br /&gt;
==== InfluxDB Platform ====&lt;br /&gt;
&lt;br /&gt;
[https://www.influxdata.com/products/influxdb-overview/ InfluxDB] is a time series database, used to store data collected by [https://www.influxdata.com/time-series-platform/telegraf/ Telegraf].  The UI layer, [https://www.influxdata.com/time-series-platform/chronograf/ Chronograf], is used to display the data in a visually useful way on the dashboard.  Finally, [https://www.influxdata.com/time-series-platform/kapacitor/ Kapacitor] is used to trigger actions based upon data values.&lt;br /&gt;
&lt;br /&gt;
==== Node-RED ====&lt;br /&gt;
&lt;br /&gt;
[https://nodered.org/ Node-RED] is used to request and interpret data from the [[Chemtrol Pool Controller]] via its RS-485 interface (over Ethernet).&lt;br /&gt;
&lt;br /&gt;
=== LCD Monitor ===&lt;br /&gt;
&lt;br /&gt;
As of 2021, the monitor is an &amp;quot;old&amp;quot; HP Compaq LA2405x.  This was an older surplus unit, chosen for its scrap bin destiny.  It&#039;s fully expected that this monitor may eventually fail due to the corrosive environment it&#039;s exposed to in the summer, along with a cold/damp/unconditioned environment in the winter.  Replacement is straightforward; screws accessible on the bottom side release it from the VESA wall mount.  Any monitor with HD or better resolution and an HDMI input should suffice.&lt;br /&gt;
&lt;br /&gt;
== Gauges ==&lt;br /&gt;
&lt;br /&gt;
Gauge measurements are averaged in both the PLC and dashboard software.  Gauges may take several seconds (or longer) to respond to significant changes in system conditions.&lt;br /&gt;
&lt;br /&gt;
=== Filter Tank Pressure ===&lt;br /&gt;
&lt;br /&gt;
[[File:Tank Pressure Gauge Example.png|frame|An example of a tank pressure gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the pressure in pounds per square inch (psi) for a [[Sand Filters|sand filter]] tank per the PLC [[Pool Systems Automation#Filter Tank Pressure|Filter Tank Pressure]] measurement (via WiFi link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(psi)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0-4&lt;br /&gt;
|Red&lt;br /&gt;
|Critically Low Pressure (Pump/Flow Issue)&lt;br /&gt;
|-&lt;br /&gt;
|4-8&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Pressure (Flow Issue) - Consider [[Cleaning the Strainer Basket]]&lt;br /&gt;
|-&lt;br /&gt;
|8-18&lt;br /&gt;
|Green&lt;br /&gt;
|Normal Operating Pressure&lt;br /&gt;
|-&lt;br /&gt;
|18+&lt;br /&gt;
|Yellow/Red&lt;br /&gt;
|[[Backwashing|Backwash]] Recommended&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For consistent indication, the values above and dashboard visualization thresholds should always align with those defined within the [[Pool Systems Automation#Filter Tank Pressure|PLC thresholds]].&lt;br /&gt;
&lt;br /&gt;
Tank pressure is lowest when the [[Cleaning the Strainer Basket|strainer basket is clean]] and the sand filters have been recently [[Backwashing|backwashed]].  If pump outflow is restricted enough (in an effort to [[Pool Main Pump#Flow Rate|maintain proper flow]], it is possible for pressure to dip into the &amp;quot;Low Pressure&amp;quot; range.  This is not necessarily a cause for any concern.&lt;br /&gt;
&lt;br /&gt;
If the associated sensor is in a fault state (the sensor has failed, there is a wiring/fuse fault or the connector is unplugged), the gauge will show a value of 0.0.  A fault state is indicated by the PLC and the stack light.  If the gauge is not visible (the block is blank), a communication error with the PLC has occurred or a software issue is present on the dashboard PC.  Consult the system administrator.&lt;br /&gt;
&lt;br /&gt;
=== Surge Tank Level ===&lt;br /&gt;
&lt;br /&gt;
[[File:Surge Tank Depth Gauge Example.png|frame|An example of the surge tank level (depth) gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the level (depth) in inches for the surge tank per the PLC [[Pool Systems Automation#Surge Tank Level|Surge Tank Level]] measurement (via WiFi link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(in)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 16&lt;br /&gt;
|Red&lt;br /&gt;
|Critical Level&lt;br /&gt;
|-&lt;br /&gt;
|16-46&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Level (Auto-Fill Threshold)&lt;br /&gt;
|-&lt;br /&gt;
|46-60&lt;br /&gt;
|Green&lt;br /&gt;
|Nominal Level (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|60-76&lt;br /&gt;
|Blue&lt;br /&gt;
|Excess Level&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 76&lt;br /&gt;
|Red&lt;br /&gt;
|Overflow Level&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:  The &amp;quot;Nominal Level&amp;quot; of the surge tank is subject to future revision.  At this time, lacking a proper drain modulating valve, it is not possible to provide &amp;quot;surge&amp;quot; capacity (keep the tank level lowered during periods of high gutter flow).  As a result, some portion of the &amp;quot;Nominal Level&amp;quot; and &amp;quot;Excess Level&amp;quot; is expected when the pool level is high and/or there is a large amount of activity in the pool.  Ideally, the surge tank should usually remain below the gutter inlet level.&lt;br /&gt;
&lt;br /&gt;
When the &amp;quot;Critical Level&amp;quot; threshold is met, this may result in pump shutdown (per the PLC) to prevent pulling air into the pump.  The surge tank water level is insufficient to maintain operation.  When enabled, auto-fill begins at the upper end of the &amp;quot;Low Level&amp;quot; threshold and ends when the upper end of the &amp;quot;Nominal Level&amp;quot; is met.  A large amount of surge tank level hysteresis is needed when an actual pool level measurement is lacking.&lt;br /&gt;
&lt;br /&gt;
The tank nears overflow at the &amp;quot;Overflow Level&amp;quot; threshold.  No specific action is taken by the PLC at this point.&lt;br /&gt;
&lt;br /&gt;
=== Out Flow ===&lt;br /&gt;
&lt;br /&gt;
[[File:Out Flow Gauge Example.png|frame|An example of the out flow rate gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the out flow rate in gallons per minute (GPM).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 490&lt;br /&gt;
|Red&lt;br /&gt;
|Very Low Flow&lt;br /&gt;
|-&lt;br /&gt;
|490-570&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Flow (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|570-670&lt;br /&gt;
|Green&lt;br /&gt;
|Optimal Flow&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 670&lt;br /&gt;
|Yellow&lt;br /&gt;
|High Flow&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A target flow rate of 600 GPM has been established for manual adjustment.  This flow rate:&lt;br /&gt;
&lt;br /&gt;
* Meets the minimum pool turnover rate of 4 times per day (every 6 hours) for a 203,500 gallon pool.&lt;br /&gt;
* Is within some margin of the maximum flow rate set by the sand filters (140 GPM x 4 = 580 GPM).&lt;br /&gt;
&lt;br /&gt;
To prevent [[Sand Filters#Channeling|channeling]] in the sand filters, an upper bound of 670 GPM has been set (somewhat arbitrarily).  The operator should try to keep as close to 600 GPM operation as possible (without dipping below 570 GPM).&lt;br /&gt;
&lt;br /&gt;
=== Inlet Temperature ===&lt;br /&gt;
&lt;br /&gt;
[[File:Inlet Temperature Gauge Example.png|frame|An example of the inlet temperature gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the inlet temperature in degrees Fahrenheit (&amp;amp;deg;F) per the temperature controller measurement (via WiFi link).  This temperature is measured directly after the filter tanks, prior to the boiler loop (refer to the [[Process Flow Diagram]]).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 79&lt;br /&gt;
|Blue&lt;br /&gt;
|Low Temperature (Temperature Controller Alarm)&lt;br /&gt;
|-&lt;br /&gt;
|79-81&lt;br /&gt;
|Yellow&lt;br /&gt;
|Low Temperature (Outside of Controlled Bounds)&lt;br /&gt;
|-&lt;br /&gt;
|81+&lt;br /&gt;
|Green&lt;br /&gt;
|Normal Temperature&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The boiler is nominally set to 82 &amp;amp;deg;F.  Controller hysteresis keeps the temperature to within &amp;amp;plusmn;1 &amp;amp;deg;F or less.  The temperature controller enters an &amp;quot;alarm&amp;quot; state indicating that the boiler may be in a fault state once the temperature is below 79 &amp;amp;deg;F.  During hot summer days, temperatures of 82 &amp;amp;deg;F to 87 &amp;amp;deg;F are expected and normal.&lt;br /&gt;
&lt;br /&gt;
=== pH ===&lt;br /&gt;
&lt;br /&gt;
[[File:pH Gauge Example.png|frame|An example of the pH gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the sampled water pH per a [[Chemtrol Pool Controller]] measurement (via RS-485/Ethernet link).&lt;br /&gt;
&lt;br /&gt;
The color bands are determined as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Range&amp;lt;br&amp;gt;(&amp;amp;deg;F)&lt;br /&gt;
!Color&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; 7.2&lt;br /&gt;
|Red&lt;br /&gt;
|Corrosive Water (See Note)&lt;br /&gt;
|-&lt;br /&gt;
|7.2-7.4&lt;br /&gt;
|Yellow&lt;br /&gt;
|pH Low&lt;br /&gt;
|-&lt;br /&gt;
|7.4-7.6&lt;br /&gt;
|Green&lt;br /&gt;
|pH Ideal&lt;br /&gt;
|-&lt;br /&gt;
|7.6-7.8&lt;br /&gt;
|Yellow&lt;br /&gt;
|pH High&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; 7.8&lt;br /&gt;
|Red&lt;br /&gt;
|Scaling Water (See Note)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: Ideal pH is between 7.4 and 7.6.  A pH between 7.2 and 7.8 is generally acceptable (though possibly too low or too high).  A pH below 7.2 or above 7.8 may be problematic; verify by calculating the Langelier Saturation Index (LSI).&lt;br /&gt;
&lt;br /&gt;
=== ORP ===&lt;br /&gt;
&lt;br /&gt;
[[File:ORP Gauge Example.png|frame|An example of the ORP gauge.]]&lt;br /&gt;
&lt;br /&gt;
Shows the sampled water oxidation reduction potential (ORP) per a [[Chemtrol Pool Controller]] measurement (via RS-485/Ethernet link).&lt;br /&gt;
&lt;br /&gt;
== Graphs ==&lt;br /&gt;
&lt;br /&gt;
=== ORP ===&lt;br /&gt;
&lt;br /&gt;
[[File:ORP Graph Example.png|frame|An example of an ORP graph.]]&lt;br /&gt;
&lt;br /&gt;
The ORP graph shows the ORP measurement over time.  The graph shown contains two days worth of history.  Certain events, marked by numbers, can be identified:&lt;br /&gt;
&lt;br /&gt;
# A valley indicates a ORP trend direction change.  This typically occurs when chlorine is added to the pool.&lt;br /&gt;
# Overshoot and leveling-off is common overnight, as a lack of UV (and to some extent, pool occupants) prevents the rapid breakdown of chlorine in the pool water.&lt;br /&gt;
# Two events are identified in this marker.  First, the gradual drop in ORP as the sun hits the pool (starting at about 7:30 am).  Then, like in #1, a rise in ORP as chlorine is added to the pool.  Overshoot is much lower in this instance, as the pool is occupied and mid-day sunshine contributes to rapid chlorine breakdown.&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Chemical_Orders&amp;diff=1772</id>
		<title>Chemical Orders</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Chemical_Orders&amp;diff=1772"/>
		<updated>2025-02-26T01:47:17Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Pool chemical orders are tracked on this page.  Do not post costs here as they may be considered proprietary to the supplier (not public).&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=2|Year&lt;br /&gt;
!colspan=5|Order (Start of Season)&lt;br /&gt;
!colspan=5|Inventory (End of Season)&lt;br /&gt;
!colspan=5|Usage&lt;br /&gt;
|-&lt;br /&gt;
!Ca(ClO)₂&lt;br /&gt;
!HCl&lt;br /&gt;
!CaCl₂&lt;br /&gt;
!NaHCO₃&lt;br /&gt;
!(CNOH)₃&lt;br /&gt;
!Ca(ClO)₂&lt;br /&gt;
!HCl&lt;br /&gt;
!CaCl₂&lt;br /&gt;
!NaHCO₃&lt;br /&gt;
!(CNOH)₃&lt;br /&gt;
!Ca(ClO)₂&lt;br /&gt;
!HCl&lt;br /&gt;
!CaCl₂&lt;br /&gt;
!NaHCO₃&lt;br /&gt;
!(CNOH)₃&lt;br /&gt;
|-&lt;br /&gt;
!2016&lt;br /&gt;
|50&lt;br /&gt;
|108&lt;br /&gt;
|3&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|colspan=10|No Data&lt;br /&gt;
|-&lt;br /&gt;
!2017&lt;br /&gt;
|40&lt;br /&gt;
|212&lt;br /&gt;
|1&lt;br /&gt;
|7&lt;br /&gt;
|4&lt;br /&gt;
|colspan=10|No Data&lt;br /&gt;
|-&lt;br /&gt;
!2018&lt;br /&gt;
|63&lt;br /&gt;
|132&lt;br /&gt;
|1&lt;br /&gt;
|3&lt;br /&gt;
|2&lt;br /&gt;
|colspan=10|No Data&lt;br /&gt;
|-&lt;br /&gt;
!2019&lt;br /&gt;
|72&lt;br /&gt;
|160&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|colspan=10|No Data&lt;br /&gt;
|-&lt;br /&gt;
!2020&lt;br /&gt;
|30&lt;br /&gt;
|120&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|130&lt;br /&gt;
|4&lt;br /&gt;
|0&lt;br /&gt;
|3&lt;br /&gt;
|colspan=5|No Data&lt;br /&gt;
|-&lt;br /&gt;
!2021&lt;br /&gt;
|60&lt;br /&gt;
|30&lt;br /&gt;
|0&lt;br /&gt;
|11&lt;br /&gt;
|TBD&lt;br /&gt;
|10&lt;br /&gt;
|15&lt;br /&gt;
|3&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|55&lt;br /&gt;
|145&lt;br /&gt;
|1&lt;br /&gt;
|11&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
!2022&lt;br /&gt;
|55+10&lt;br /&gt;
|152&lt;br /&gt;
|0&lt;br /&gt;
|8&lt;br /&gt;
|4&lt;br /&gt;
|9&lt;br /&gt;
|32&lt;br /&gt;
|3&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|66&lt;br /&gt;
|135&lt;br /&gt;
|0&lt;br /&gt;
|8&lt;br /&gt;
|4&lt;br /&gt;
|-&lt;br /&gt;
!2023&lt;br /&gt;
|55&lt;br /&gt;
|140&lt;br /&gt;
|0&lt;br /&gt;
|8&lt;br /&gt;
|6&lt;br /&gt;
|colspan=5|Did Not Inventory (see 2024 notes)&lt;br /&gt;
|colspan=5|Unknown&lt;br /&gt;
|-&lt;br /&gt;
!2024&lt;br /&gt;
|60&lt;br /&gt;
|160&lt;br /&gt;
|0&lt;br /&gt;
|8&lt;br /&gt;
|4&lt;br /&gt;
|21&lt;br /&gt;
|8&lt;br /&gt;
|0&lt;br /&gt;
|TBD&lt;br /&gt;
|3&lt;br /&gt;
|colspan=5|Unknown&lt;br /&gt;
|-&lt;br /&gt;
!2025&lt;br /&gt;
|55&lt;br /&gt;
|172&lt;br /&gt;
|0&lt;br /&gt;
|8&lt;br /&gt;
|0&lt;br /&gt;
|colspan=5|TBD&lt;br /&gt;
|colspan=5|TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Key:&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;b&amp;gt;Order&amp;lt;/b&amp;gt; column contains the total number of units ordered for the entire season.  If subsequent orders or made (beyond the pre-season order), this should be noted in the notes, below.&lt;br /&gt;
* The &amp;lt;b&amp;gt;Inventory&amp;lt;/b&amp;gt; column contains the total number of units on-hand at the end of the season.&lt;br /&gt;
* The &amp;lt;b&amp;gt;Usage&amp;lt;/b&amp;gt; column contains the number of units used during the season (the prior year&#039;s inventory plus the order minus the usage). &lt;br /&gt;
* &amp;lt;b&amp;gt;Ca(ClO)₂&amp;lt;/b&amp;gt; is Calcium Hypochlorite - see 2024 notes for details.&lt;br /&gt;
* &amp;lt;b&amp;gt;HCl&amp;lt;/b&amp;gt; is hydrochloric (muriatic) acid, measured in 1-gallon containers.  Typically 4 gallons are packed in a case.&lt;br /&gt;
* &amp;lt;b&amp;gt;CaCl₂&amp;lt;/b&amp;gt; is calcium chloride, measured in 50-lb bags.&lt;br /&gt;
* &amp;lt;b&amp;gt;NaHCO₃&amp;lt;/b&amp;gt; is sodium bicarbonate, measured in 50-lb bags.&lt;br /&gt;
* &amp;lt;b&amp;gt;(CNOH)₃&amp;lt;/b&amp;gt; is cyanuric acid (CYA, stabilizer), measured in 25-lb buckets.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
=== Pre-2021 ===&lt;br /&gt;
&lt;br /&gt;
Chemical orders were not well-tracked.  Early season discounts were not fully utilized due to repeat orders (sometimes up to 5 orders in a season, resulting in added delivery charges).&lt;br /&gt;
&lt;br /&gt;
=== 2021 ===&lt;br /&gt;
&lt;br /&gt;
The chemical order was based on 2016 through 2019 averages.  The result was a planned excess of some chlorine and acid.  No additional orders for chlorine and acid were made, so the pre-season discounts were fully utilized.&lt;br /&gt;
&lt;br /&gt;
However, excess purchase of sodium bicarbonate was necessary to keep the pool alkalinity in range (compared to data from 2016-2019).  The amount of stabilizer in the pool was also regularly low.&lt;br /&gt;
&lt;br /&gt;
=== 2022 ===&lt;br /&gt;
&lt;br /&gt;
Starting in 2022, it was determined that there is no need to purchase calcium chloride.  The calcium added by the calcium hypochlorite, in addition to the hardness in the city water supply, is more than sufficient to keep the water hardness within desired bounds.&lt;br /&gt;
&lt;br /&gt;
The early season discounts ended in 2022 (with our primary supplier) due to inflation and supply chain issues.  We still aim to purchase all chemicals up-front to minimize delivery charges.&lt;br /&gt;
&lt;br /&gt;
A high burn rate of sanitizer was observed in early 2022.  A modest stabilizer level is deemed necessary in the pool water.&lt;br /&gt;
&lt;br /&gt;
=== 2024 ===&lt;br /&gt;
&lt;br /&gt;
In 2024, the chlorinator was changed from an [https://accu-tab.com/ Accu-Tab] tablet system (which used 60-lb buckets) to a Pulsar briquette system (which uses 50-lb buckets).  Inventory and usage to be noted as such.  Unfortunately, it appears the during the changeover period, we did not inventory chemicals on-hand.  So, usage for 2023 and 2024 is unknown (unless the missing inventory data is located).&lt;br /&gt;
&lt;br /&gt;
=== 2025 ===&lt;br /&gt;
&lt;br /&gt;
Lacking data for usage in 2023 and 2024, it&#039;s a bit difficult to know how much chlorine is required.  With 21 buckets on-hand, 55 additional buckets will be ordered.  As these buckets are 50 lb, this will be equivalent to having about 61 x 60-lb buckets post-order.  It&#039;s not clear if the Pulsar system uses more or less chlorine - again, lacking data (and also lacking supporting data for burn rate based on weather and pool usage).  As acid was nearly depleted in 2024, ordering extra (172) for 2025 may make sense.  If memory serves, we nearly ran out in 2023.&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Chemical_Orders&amp;diff=1771</id>
		<title>Chemical Orders</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Chemical_Orders&amp;diff=1771"/>
		<updated>2025-02-26T01:36:25Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Pool chemical orders are tracked on this page.  Do not post costs here as they may be considered proprietary to the supplier (not public).&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=2|Year&lt;br /&gt;
!colspan=5|Order (Start of Season)&lt;br /&gt;
!colspan=5|Inventory (End of Season)&lt;br /&gt;
!colspan=5|Usage&lt;br /&gt;
|-&lt;br /&gt;
!Ca(ClO)₂&lt;br /&gt;
!HCl&lt;br /&gt;
!CaCl₂&lt;br /&gt;
!NaHCO₃&lt;br /&gt;
!(CNOH)₃&lt;br /&gt;
!Ca(ClO)₂&lt;br /&gt;
!HCl&lt;br /&gt;
!CaCl₂&lt;br /&gt;
!NaHCO₃&lt;br /&gt;
!(CNOH)₃&lt;br /&gt;
!Ca(ClO)₂&lt;br /&gt;
!HCl&lt;br /&gt;
!CaCl₂&lt;br /&gt;
!NaHCO₃&lt;br /&gt;
!(CNOH)₃&lt;br /&gt;
|-&lt;br /&gt;
!2016&lt;br /&gt;
|50&lt;br /&gt;
|108&lt;br /&gt;
|3&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|colspan=10|No Data&lt;br /&gt;
|-&lt;br /&gt;
!2017&lt;br /&gt;
|40&lt;br /&gt;
|212&lt;br /&gt;
|1&lt;br /&gt;
|7&lt;br /&gt;
|4&lt;br /&gt;
|colspan=10|No Data&lt;br /&gt;
|-&lt;br /&gt;
!2018&lt;br /&gt;
|63&lt;br /&gt;
|132&lt;br /&gt;
|1&lt;br /&gt;
|3&lt;br /&gt;
|2&lt;br /&gt;
|colspan=10|No Data&lt;br /&gt;
|-&lt;br /&gt;
!2019&lt;br /&gt;
|72&lt;br /&gt;
|160&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|colspan=10|No Data&lt;br /&gt;
|-&lt;br /&gt;
!2020&lt;br /&gt;
|30&lt;br /&gt;
|120&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|130&lt;br /&gt;
|4&lt;br /&gt;
|0&lt;br /&gt;
|3&lt;br /&gt;
|colspan=5|No Data&lt;br /&gt;
|-&lt;br /&gt;
!2021&lt;br /&gt;
|60&lt;br /&gt;
|30&lt;br /&gt;
|0&lt;br /&gt;
|11&lt;br /&gt;
|TBD&lt;br /&gt;
|10&lt;br /&gt;
|15&lt;br /&gt;
|3&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|55&lt;br /&gt;
|145&lt;br /&gt;
|1&lt;br /&gt;
|11&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
!2022&lt;br /&gt;
|55+10&lt;br /&gt;
|152&lt;br /&gt;
|0&lt;br /&gt;
|8&lt;br /&gt;
|4&lt;br /&gt;
|9&lt;br /&gt;
|32&lt;br /&gt;
|3&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|66&lt;br /&gt;
|135&lt;br /&gt;
|0&lt;br /&gt;
|8&lt;br /&gt;
|4&lt;br /&gt;
|-&lt;br /&gt;
!2023&lt;br /&gt;
|55&lt;br /&gt;
|140&lt;br /&gt;
|0&lt;br /&gt;
|8&lt;br /&gt;
|6&lt;br /&gt;
|colspan=5|Did Not Inventory (see 2024 notes)&lt;br /&gt;
|colspan=5|Unknown&lt;br /&gt;
|-&lt;br /&gt;
!2024&lt;br /&gt;
|60&lt;br /&gt;
|160&lt;br /&gt;
|0&lt;br /&gt;
|8&lt;br /&gt;
|4&lt;br /&gt;
|21&lt;br /&gt;
|8&lt;br /&gt;
|0&lt;br /&gt;
|TBD&lt;br /&gt;
|3&lt;br /&gt;
|colspan=5|Unknown&lt;br /&gt;
|-&lt;br /&gt;
!2025&lt;br /&gt;
|50&lt;br /&gt;
|172&lt;br /&gt;
|0&lt;br /&gt;
|6&lt;br /&gt;
|0&lt;br /&gt;
|colspan=5|TBD&lt;br /&gt;
|colspan=5|TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Key:&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;b&amp;gt;Order&amp;lt;/b&amp;gt; column contains the total number of units ordered for the entire season.  If subsequent orders or made (beyond the pre-season order), this should be noted in the notes, below.&lt;br /&gt;
* The &amp;lt;b&amp;gt;Inventory&amp;lt;/b&amp;gt; column contains the total number of units on-hand at the end of the season.&lt;br /&gt;
* The &amp;lt;b&amp;gt;Usage&amp;lt;/b&amp;gt; column contains the number of units used during the season (the prior year&#039;s inventory plus the order minus the usage). &lt;br /&gt;
* &amp;lt;b&amp;gt;Ca(ClO)₂&amp;lt;/b&amp;gt; is Calcium Hypochlorite - see 2024 notes for details.&lt;br /&gt;
* &amp;lt;b&amp;gt;HCl&amp;lt;/b&amp;gt; is hydrochloric (muriatic) acid, measured in 1-gallon containers.  Typically 4 gallons are packed in a case.&lt;br /&gt;
* &amp;lt;b&amp;gt;CaCl₂&amp;lt;/b&amp;gt; is calcium chloride, measured in 50-lb bags.&lt;br /&gt;
* &amp;lt;b&amp;gt;NaHCO₃&amp;lt;/b&amp;gt; is sodium bicarbonate, measured in 50-lb bags.&lt;br /&gt;
* &amp;lt;b&amp;gt;(CNOH)₃&amp;lt;/b&amp;gt; is cyanuric acid (CYA, stabilizer), measured in 25-lb buckets.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
=== Pre-2021 ===&lt;br /&gt;
&lt;br /&gt;
Chemical orders were not well-tracked.  Early season discounts were not fully utilized due to repeat orders (sometimes up to 5 orders in a season, resulting in added delivery charges).&lt;br /&gt;
&lt;br /&gt;
=== 2021 ===&lt;br /&gt;
&lt;br /&gt;
The chemical order was based on 2016 through 2019 averages.  The result was a planned excess of some chlorine and acid.  No additional orders for chlorine and acid were made, so the pre-season discounts were fully utilized.&lt;br /&gt;
&lt;br /&gt;
However, excess purchase of sodium bicarbonate was necessary to keep the pool alkalinity in range (compared to data from 2016-2019).  The amount of stabilizer in the pool was also regularly low.&lt;br /&gt;
&lt;br /&gt;
=== 2022 ===&lt;br /&gt;
&lt;br /&gt;
Starting in 2022, it was determined that there is no need to purchase calcium chloride.  The calcium added by the calcium hypochlorite, in addition to the hardness in the city water supply, is more than sufficient to keep the water hardness within desired bounds.&lt;br /&gt;
&lt;br /&gt;
The early season discounts ended in 2022 (with our primary supplier) due to inflation and supply chain issues.  We still aim to purchase all chemicals up-front to minimize delivery charges.&lt;br /&gt;
&lt;br /&gt;
A high burn rate of sanitizer was observed in early 2022.  A modest stabilizer level is deemed necessary in the pool water.&lt;br /&gt;
&lt;br /&gt;
=== 2024 ===&lt;br /&gt;
&lt;br /&gt;
In 2024, the chlorinator was changed from an [https://accu-tab.com/ Accu-Tab] tablet system (which used 60-lb buckets) to a Pulsar briquette system (which uses 50-lb buckets).  Inventory and usage to be noted as such.  Unfortunately, it appears the during the changeover period, we did not inventory chemicals on-hand.  So, usage for 2023 and 2024 is unknown (unless the missing inventory data is located).&lt;br /&gt;
&lt;br /&gt;
=== 2025 ===&lt;br /&gt;
&lt;br /&gt;
Lacking data for usage in 2023 and 2024, it&#039;s a bit difficult to know how much chlorine is required.  With 21 buckets on-hand, 50 additional buckets will be ordered.  As these buckets are 50 lb, this is equivalent to about 57 x 60-lb buckets.  It&#039;s not clear if the Pulsar system uses more or less chlorine - again, lacking data (and also lacking supporting data for burn rate based on weather and pool usage).  As acid was nearly depleted in 2024, ordering extra (172) for 2025 may make sense.  If memory serves, we nearly ran out in 2023.&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Head_Swim_Coach_Responsibilities&amp;diff=1770</id>
		<title>Head Swim Coach Responsibilities</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Head_Swim_Coach_Responsibilities&amp;diff=1770"/>
		<updated>2025-01-28T02:40:30Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: This is the initial revision, input from verbiage provided by the swim team coordinators.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Assistant Coaches ==&lt;br /&gt;
Work with and manage. Guide them to be the best coach they can.&lt;br /&gt;
&lt;br /&gt;
== Practice ==&lt;br /&gt;
&lt;br /&gt;
* Monday – Friday 7:30 am – 10:30 am (times may vary).&lt;br /&gt;
* In accordance with lifeguard restrictions available coaches should be in the water coaching swimmers. Swim strokes, flip turns, diving of the block, and relay transitions should all be taught.&lt;br /&gt;
* &#039;&#039;&#039;Fun Friday&#039;&#039;&#039; takes place at the same time as practice with the kids playing age appropriate games in the water and receiving donuts at the end of practice.&lt;br /&gt;
&lt;br /&gt;
== Meets ==&lt;br /&gt;
&lt;br /&gt;
* Tuesday &amp;amp; Thursday 4:15 pm – 9:30 pm (times may vary).&lt;br /&gt;
* All administrative duties must be completed by 4 pm on meet days (list will be provided).&lt;br /&gt;
* Show up before swimmers and set up boards.&lt;br /&gt;
* WIN, WIN, WIN - or at least try!&lt;br /&gt;
&lt;br /&gt;
== Extras ==&lt;br /&gt;
&lt;br /&gt;
* Kickoff Meeting&lt;br /&gt;
* Practice Meets&lt;br /&gt;
* Skill Clinics&lt;br /&gt;
* Team Activities (times will be discussed before finalized)&lt;br /&gt;
* Fire-up Dinner (the Friday before League Meet)&lt;br /&gt;
* Swim Banquet (immediately following League Meet, at Fairway Farms)&lt;br /&gt;
* Attend Presidents Meeting and the Coaches Meeting&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* High School Diploma or GED&lt;br /&gt;
* CPR &amp;amp; AED Certified&lt;br /&gt;
* Lifeguard Certification&lt;br /&gt;
* Pass a Criminal Background Check&lt;br /&gt;
&lt;br /&gt;
== Administrative Tasks ==&lt;br /&gt;
&lt;br /&gt;
* Learn SISL rules.&lt;br /&gt;
* Input swimmer information into &#039;&#039;&#039;Team Manager&#039;&#039;&#039; and become familiar with &#039;&#039;&#039;Team Manager&#039;&#039;&#039;.&lt;br /&gt;
* Track swimmer availability using the registration form.&lt;br /&gt;
* Track swimmers’ best times.&lt;br /&gt;
* Create swim line-up ensuring every swimmer participates in 2 -3 events in each meet in accordance with the rules.&lt;br /&gt;
* Be sure there are 30 or less exhibition heats.&lt;br /&gt;
* Consult with coach from opposing team by 3 pm the day before to be sure exhibition heats line up.&lt;br /&gt;
* Enter 8 dual meets into &#039;&#039;&#039;Team Manager&#039;&#039;&#039;.&lt;br /&gt;
* Generate heat sheets, event sheets, print and label cards for all events and organize in card box.&lt;br /&gt;
* Make copies of heat sheets for all coaches.&lt;br /&gt;
* Create event board at all meets.&lt;br /&gt;
* Track Fairway records and update.&lt;br /&gt;
* Changes can be made up until the meet starts must know what to do if a swimmer can not attend a meet last minute.&lt;br /&gt;
* &#039;&#039;&#039;Barracuda of the Week&#039;&#039;&#039;.&lt;br /&gt;
* League Meet – follow all rules of SISL, set up line up and enter into &#039;&#039;&#039;Team Manager&#039;&#039;&#039;.&lt;br /&gt;
* Banquet - Towels for swimmers 18+ and last year of swimming embroidered with names, paper plate awards for every swimmer (or another award), speech.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Please know while this is the majority of the job description there may be other tasks assigned, within reason.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Asset_Registry&amp;diff=1768</id>
		<title>Asset Registry</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Asset_Registry&amp;diff=1768"/>
		<updated>2025-01-04T13:17:36Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Asset Registry is maintained by Building &amp;amp; Grounds and reviewed by the board.  The original version was created by Sally Duffy and the 2020 Capital Assessment Committee.&lt;br /&gt;
&lt;br /&gt;
Where possible, inflation is considered (using [https://smartasset.com/investing/inflation-calculator this calculator], for instance).  Future investment is a &amp;quot;best guess&amp;quot; based upon past quotes or work, where possible.  NOTE: A higher-than-expected inflation rate took effect in 2022.  This has not necessarily been factored into calculations (August 2022).  Many estimates were made in 2020 and 2021.&lt;br /&gt;
&lt;br /&gt;
Columns for &amp;lt;b&amp;gt;Failure Mode and Effect Analysis (FMEA)&amp;lt;/b&amp;gt; were added in January 2023.  The columns are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Severity (S):&amp;lt;/b&amp;gt; 1 = insignificant (minimal operational impact); 10 = catastrophic (the club cannot operate)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Occurrence (O):&amp;lt;/b&amp;gt; 1 = extremely unlikely; 10 = inevitable&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Detection (D):&amp;lt;/b&amp;gt; 1 = certain to detect; 10 = certain not to detect&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Risk Priority Number (RPN):&amp;lt;/b&amp;gt; The product of O, S and D.  0 = low risk; 1000 = highest risk&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FMEA Values are subjective.  The threshold of concern (for the RPN) is generally set to 200, though subject to revision.&lt;br /&gt;
&lt;br /&gt;
== Basement ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=This section was partially updated on January 4th, 2025.}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable mw-collapsible&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|FMEA&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2025)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
!S&lt;br /&gt;
!O&lt;br /&gt;
!D&lt;br /&gt;
!RPN&lt;br /&gt;
|-&lt;br /&gt;
|Aquastat&lt;br /&gt;
|2024&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|19&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$500&lt;br /&gt;
|3&lt;br /&gt;
|2&lt;br /&gt;
|3&lt;br /&gt;
|18&lt;br /&gt;
|A Honeywell T775A2009 aquastat (electronic temperature control) was installed on the hot water circulator pump to prevent thermal run-away and support immediate hot water at the sinks and showers.&lt;br /&gt;
|-&lt;br /&gt;
|Breaker Panel ([[Electrical System#Basement Panel RLP-2|RLP-2]])&lt;br /&gt;
|1966&lt;br /&gt;
|2020&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|10&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|100&lt;br /&gt;
|The basement breaker panel is a Square D QO series (copper bus bar).  It is in good operating condition.  No plans to replace it for the foreseeable future.  The wiring was cleaned up and the branch side lugs were properly torqued in 2020.  New circuits added.  Very limited capacity left - additional circuits should be added to the upstairs panel (RLP-1).&lt;br /&gt;
|-&lt;br /&gt;
|Circulator Pump (Hot Water)&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|6&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$420&lt;br /&gt;
|&lt;br /&gt;
|3&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|75&lt;br /&gt;
|The hot water circulator pump is a Grundfos Alpha2 15-55SFC (99163937) stainless steel circulation pump (1/16 HP).  The replacement cost is $330 in 2021 (maybe cheaper on surplus).  Circulation pumps are cited to last ten years - but as always, subject to environment and use.  As of 2021, it was noted that the circulation function didn&#039;t really work correctly.  In 2024, an aquastat was added to (finally) address the issues.&lt;br /&gt;
|-&lt;br /&gt;
|Dehumidifier &amp;quot;A&amp;quot;&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|0&lt;br /&gt;
|$330&lt;br /&gt;
|$380&lt;br /&gt;
|$420&lt;br /&gt;
|$480&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|3&lt;br /&gt;
|192&lt;br /&gt;
|The existing model is a Toshiba TDDP5012ES2 50pint/day unit (DOM: 08/2019, but not placed into service until 2020).  The replacement cost is $300.  Dehumidifiers tend to be short-lived (especially in high humidity, high-duty cycle environments).  It is estimated that this unit may only last five years.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;B&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; While the severity of a failure is high (mold growth, if not resolved), this unit is easily replaceable and poses no risk to the operating status of the club.&lt;br /&gt;
|-&lt;br /&gt;
|Dehumidifier &amp;quot;B&amp;quot;&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|1&lt;br /&gt;
|$340&lt;br /&gt;
|$380&lt;br /&gt;
|$430&lt;br /&gt;
|$490&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|3&lt;br /&gt;
|192&lt;br /&gt;
|The existing model is a Frigidaire (Electrolux) FGAC7044U101 (DOM: 01/2019, but not placed into service until 2021).  The replacement cost is $300.  See the comments for &amp;lt;b&amp;gt;Dehumidifier &amp;quot;A&amp;quot;&amp;lt;/b&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|6&lt;br /&gt;
|$30&lt;br /&gt;
|$180&lt;br /&gt;
|$40&lt;br /&gt;
|$230&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The basement fire extinguisher is a Buckeye ABC unit (exact model TBD).  Six-year maintenance ($38 in 2021 dollars) is due in 2027 and 2037 (was originally due in 2023 per manufacture date but occurred in 2021).  Replacement ($90 in 2021 dollars) is due in 2029 and 2041.  Annual servicing ($6 in 2021 dollars) is required.  Prices are adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Foundation/Walls&lt;br /&gt;
|1966&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|18&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|$16,000&lt;br /&gt;
|7&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|175&lt;br /&gt;
|Installed a new internal weeping tile system and sump pump in 2021.  Assume that after 20 years, the system may need to be replaced (again) due to the eventual infiltration of sediment.  Painted basement walls with Liquid Rubber and Drylok in 2021.  Hydrostatic pressure is causing a bulge on the east wall (near the staircase).  TBD cost to address in the 5-10 year window (as of 2021) unless movement/cracking makes the project more urgent.  As of 2022, some breakdown is visible in the corners (discoloration, visible water).  This may be corrected on a spot basis.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Chest)&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|20&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|8&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|32&lt;br /&gt;
|The existing model is a Kelvinator Commercial KCCF170WH (59 1/2&amp;quot;, 17 cu ft capacity).  The date of manufacture is not known.  The replacement cost in 2021 is about $930.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Chest)&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|14&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$1,300&lt;br /&gt;
|8&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|32&lt;br /&gt;
|The existing model is an Electrolux KCCF160QWA commercial freezer (15.58 cu ft capacity).  This model does not appear to be made anymore; replacement with a KCCF170WH or equivalent (replacement cost in 2021 is about $930; about $1,300 in 2036 with inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Upright)&lt;br /&gt;
|2013&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|11&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|8&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|32&lt;br /&gt;
|The existing model is a Whirlpool EV161NZTQ02 household freezer.  The replacement cost is not known at this time.&lt;br /&gt;
|-&lt;br /&gt;
|Main Distribution Panel&lt;br /&gt;
|1966&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|10&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|100&lt;br /&gt;
|The distribution panel was informally inspected in 2021.  No signs of issues.  No plans for service or replacement soon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;B&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; Regular inspections are required.&lt;br /&gt;
|-&lt;br /&gt;
|Network Equipment&lt;br /&gt;
|2024&lt;br /&gt;
|2024&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|5&lt;br /&gt;
|3&lt;br /&gt;
|2&lt;br /&gt;
|30&lt;br /&gt;
|Some equipment replacement is anticipated every five years due to product end-of-life (EOL), failures, or technology upgrades.  The cost is not known at this time.  A new PoE network switch was installed in the clubhouse in 2022 and again in 2024.  NOTE: For the sake of security, specifics about the network are not posted on the Wiki.&lt;br /&gt;
|-&lt;br /&gt;
|Sump Pump&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$300&lt;br /&gt;
|&lt;br /&gt;
|7&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|175&lt;br /&gt;
|The sump pump is a Foundation Systems of Michigan (FSM) Elite 365 AquaStop Sump Pump System (1/3 HP).  Replacement after ten years is anticipated.&lt;br /&gt;
|-&lt;br /&gt;
|Tempering Valve&lt;br /&gt;
|2020&lt;br /&gt;
|2021&lt;br /&gt;
|8&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|6&lt;br /&gt;
|&lt;br /&gt;
|$5,300&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|50&lt;br /&gt;
|The tempering valve is a Powers LFMM 433-13 (1-1/4&amp;quot; 110 GPM).  This part number (as written in the plumbing invoice) needs to be confirmed; the -13 suffix doesn&#039;t seem to align with an actual part number.  Tempering valves are cited to last 5-8 years in general.  The impact of seasonal use is TBD.  As of 2021, the functionality of the tempering valve and its interaction with the hot water circulation pump has been problematic.  An additional effort may be required in 2022.  The temperature/pressure gauge failed in 2021 and was replaced with a Watts WLFDPTG330200D.  The material and labor cost in 2020 was about $5,300; replacement in 2028 adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|UPS Batteries (Network)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$60&lt;br /&gt;
|$70&lt;br /&gt;
|$80&lt;br /&gt;
|$90&lt;br /&gt;
|3&lt;br /&gt;
|6&lt;br /&gt;
|3&lt;br /&gt;
|54&lt;br /&gt;
|The network battery backup is an APC Smart-UPS SMC1500-2U.  It uses four [https://www.power-sonic.com/product/ps-1270/ PS-1270] lead-acid batteries (the replacement cost for the Power-Sonic brand is $13 each from a local distributor).&lt;br /&gt;
|-&lt;br /&gt;
|Water Heater&lt;br /&gt;
|2007&lt;br /&gt;
|2018&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$20,000&lt;br /&gt;
|&lt;br /&gt;
|$27,000&lt;br /&gt;
|&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|512&lt;br /&gt;
|The [domestic hot] water heater is confirmed to have been installed in 2007, both by the serial number and the permit pulled noted in [[Club History#2007|club history]].  The existing unit is a Lochinvar TNR200-100 (100-gallon) fully condensing water heater.  The standard &amp;quot;rule of thumb&amp;quot; is to pre-emptively replace a water heater at the 10-year mark.  However, the fact that the water heater is drained and dormant from about September to April should have some longevity benefits.  Replacement is assumed to be necessary within the 5-10 year span (as of 2021), if not earlier.  The replacement cost is based on a quote received for labor and materials in early 2023.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; It is assumed that the domestic hot water heater is critical to club operation (for health code reasons), and the club cannot operate without it.  Detecting a failure is difficult (water heaters often fail with little to no warning once they cross the decade-old mark).  Failure is more or less &amp;quot;inevitable&amp;quot; for a residential-grade unit.  It&#039;s not clear how the commercial-grade unit differs.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* The Freezer (Ice Cream) - &amp;quot;Blue Bunny Ice Cream&amp;quot; freezer is a model RIO S125, built in 2010 - was removed from service in 2023 (or 2024?) after identifying it had failed.&lt;br /&gt;
&lt;br /&gt;
== Basketball and Tennis Courts ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=warn|text=This section was last updated in 2023 and needs to be reviewed.}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|FMEA&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2023)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
!S&lt;br /&gt;
!O&lt;br /&gt;
!D&lt;br /&gt;
!RPN&lt;br /&gt;
|-&lt;br /&gt;
|Basketball Poles&lt;br /&gt;
|2018&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|20&lt;br /&gt;
|Lifespan, replacement plans, and replacement cost are TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Surface (Basketball)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|$38,000&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are essentially four options given the court conditions:&lt;br /&gt;
# Powerwash to clean.  Fill cracks with acrylic crack filler, then resurface and paint for about $20,000.  Based on just short of 900 ft of cracks at 2020 pricing.  This is a very short-term solution; assume cracks will re-appear after a large day/night temperature swing (and especially after a freeze/thaw).  For that reason, this repair is not recommended.&lt;br /&gt;
# The same as the prior option, plus fabric overlay crack repair (2-year guarantee) for about $33,000.  This solution should last 4-5 years (after which cracks may re-appear).  This may be the best solution for the near term.  For this option, the sport coating contractor may be hired directly.&lt;br /&gt;
# Grind down 2 inches of the surface, then re-build for about $100,000 ($50,000 per court).  For this option, hire a paving contractor; the sport coating is subcontracted.&lt;br /&gt;
# Demolish, add improved drainage, then rebuild for about $150,000 ($75,000 per court).  This is by far the most expensive, but the most effective solution depending upon the underlying issues (i.e. very wet grounds).  For this option, hire a paving contractor; the sport coating is subcontracted.&lt;br /&gt;
Given current budgets, it seems likely that option #2 is the best choice for the 5-10 year window.  The lifespan of 5 years assumes repeated use of option #2.&lt;br /&gt;
|-&lt;br /&gt;
|Surface (Tennis)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|$42,000&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are essentially four options given the court conditions:&lt;br /&gt;
# Powerwash to clean.  Fill cracks with acrylic crack filler, then resurface and paint per USTA standards for about $23,000.  Based on just short of 1000 ft of cracks at 2020 pricing.  This is a very short-term solution; assume cracks will re-appear after a large day/night temperature swing (and especially after a freeze/thaw).  For that reason, this repair is not recommended.&lt;br /&gt;
# The same as the prior option, plus fabric overlay crack repair (2-year guarantee) for about $37,000.  This solution should last 4-5 years (after which cracks may re-appear).  This may be the best solution for the near term.  For this option, the sport coating contractor may be hired directly.&lt;br /&gt;
# Grind down 2 inches of the surface, then re-build for about $100,000 ($50,000 per court).  For this option, hire a paving contractor; the sport coating is sub-contracted.&lt;br /&gt;
# Demolish entirely, add improved drainage, then re-build for about $150,000 ($75,000 per court).  This is by far the most expensive, but the most effective solution depending upon the underlying issues (i.e. very wet grounds).  For this option, hire a paving contractor; the sport coating is sub-contracted.&lt;br /&gt;
Given present budgets, it seems likely that option #2 is the best choice for the 5-10 year window.  The lifespan of 5 years assumes repeated use of option #2.&lt;br /&gt;
|-&lt;br /&gt;
|Tennis Nets&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|New Edwards 30LS &amp;quot;Wimbledon Nets&amp;quot; were purchased in late 2021 and installed in the spring of 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Tennis Pole Hardware&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|$150&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The age of the existing poles is not known.  In 2022, two new &amp;quot;53420-B EZ Tennis Post Replacement Reels&amp;quot; from &amp;quot;Tennis Court Supply&amp;quot; were installed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Clubhouse ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=warn|text=This section was last updated in 2023 and needs to be reviewed.}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2023)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|Awning&lt;br /&gt;
|1997&lt;br /&gt;
|2020&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|It appears (but has not been confirmed) that the awning was installed in 1997.  The fabric material is assumed to be Sunbrella, with a 10-year rated lifespan.  However, 24 years later (as of 2021), it still looks good.  The fabric was cleaned per manufacturer recommendations in 2020.  No planned replacement until it is aesthetically necessary.&lt;br /&gt;
|-&lt;br /&gt;
|Breaker Panel ([[Electrical System#Basement Panel RLP-1|RLP-1]])&lt;br /&gt;
|2007&lt;br /&gt;
|2022&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The &amp;quot;upstairs&amp;quot; panel was added in [[Club History#2007|2007]] presumably to support additional circuits (hand dryers, etc).  There are no plans to replace it in the 20-year window.  The panel was last serviced in 2022.  Lug torques were verified, and new circuits were added.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; Regular inspections are required to meet the &amp;quot;detection&amp;quot; value.&lt;br /&gt;
|-&lt;br /&gt;
|Changing Table&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|17&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The baby changing station is a Koala Kare KB200 (replacement cost is $210 based on average online pricing as of 2021).  The lifespan is a guess and may be adjusted depending on observations of wear and tear in future years.  There is no planned replacement within the 20-year window (as of 2023).&lt;br /&gt;
|-&lt;br /&gt;
|Chimney&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The chimney is most likely original to the 1966 structure.  It is functionally obsolete; the only device producing combustion gases in the clubhouse is vented via PVC pipe.  Unfortunately, the mortar appears to be failing.  Tuckpointing is recommended shortly.  Alternatively, the chimney could potentially be removed.&lt;br /&gt;
|-&lt;br /&gt;
|Computer&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|3&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|A regular refresh cycle for the front-desk computer is planned.  The replacement cost is TBD (donated/retired business PCs preferred).&lt;br /&gt;
|-&lt;br /&gt;
|Drywall (Family Restroom Ceiling)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The family restroom ceiling was replaced in 2020 upon discovery that it was sagging several inches in the middle of the room.  No replacement is planned.&lt;br /&gt;
|-&lt;br /&gt;
|Drywall (Lobby Ceiling)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Repairs were made to the drywall near the north end (to address sagging) during the 2022 lobby renovation.  At this time, it was observed that repairs had previously been made near the &amp;quot;Fairway Farms&amp;quot; glass by the stairs.  No replacement is planned.&lt;br /&gt;
|-&lt;br /&gt;
|Electrical&lt;br /&gt;
|1966&lt;br /&gt;
|2020&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|7&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&amp;lt;p&amp;gt;Much of the wiring in the clubhouse is original to the 1966 installation.  Fortunately, #12 AWG copper was run in rigid conduit throughout.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;In 2020, the wiring was inspected and found in good condition.  Nearly all receptacles, switches, and fixtures were replaced.  All associated connections (screws, wire nuts) were removed, cleaned of oxidation, and re-terminated.  Wiring in panels ([[Electrical System#Basement Panel RLP-1|RLP-1]] and [[Electrical System#Basement Panel RLP-2|RLP-2]]) was cleaned up, and all branch-side lugs were torqued to spec.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;The basement switchgear was inspected and deemed to be in good operating condition (no replacement planned).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Replacement of certain receptacles, switches, and fixtures may be needed on a 10-year interval.  The cost is TBD.&amp;lt;/p&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Exit Signs&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$80&lt;br /&gt;
|$90&lt;br /&gt;
|$100&lt;br /&gt;
|$120&lt;br /&gt;
|The lifespan of the two exit signs is largely determined by the ability of the internal rechargeable batteries to sustain 90 minutes of illumination upon power failure.  This is an annual city inspection requirement (Livonia Code of Ordinances 15.32.030).  The battery pack may be replaceable.  If not, off-brand exit signs with floodlights can be had for as little as $40 (or less) on Amazon.&lt;br /&gt;
|-&lt;br /&gt;
|Fans (Pedestal)&lt;br /&gt;
|1995&lt;br /&gt;
|None&lt;br /&gt;
|50&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|22&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are two pedestal fans in the clubhouse.  One appears to be from 1995; the date of manufacture for the other is unknown (TBD).  The fans are anticipated to last beyond the 20-year view (as of 2021). Minor repairs may be needed; the cost is TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2016&lt;br /&gt;
|2020&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|$70&lt;br /&gt;
|$140&lt;br /&gt;
|$80&lt;br /&gt;
|$180&lt;br /&gt;
|The clubhouse (lobby) fire extinguisher is an Advantage ADV-10, as of 2021, last serviced in May 2020 (per punch tag).  Six-year maintenance ($38 in 2021 dollars) is assumed to be due in 2022 and 2034. Replacement ($90 in 2021 dollars) is due in 2028 and 2040. Annual servicing ($6 in 2021 dollars) is required. Prices are adjusted for inflation. &lt;br /&gt;
|-&lt;br /&gt;
|Floor&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Any rehabilitation or replacement of the floor in the clubhouse (main floor) is yet to be discussed.  The original installation date is not known.&lt;br /&gt;
|-&lt;br /&gt;
|Gutters&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Gutters are in disrepair (leaking) and should be replaced.  The plan is for the 5-10 year window (as of 2021).  We received quotes in 2020 that need to be located for reference.&lt;br /&gt;
|-&lt;br /&gt;
|Hand Dryers&lt;br /&gt;
|2007&lt;br /&gt;
|None&lt;br /&gt;
|25&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|The existing American Dryer (Global Dryer) model GX1 units were installed in [[Club_History#2007|2007]].  Lifespan is a guess.  The estimated cost is for two replacement units in 2032 ($150/ea in 2021 prices).  Labor is not included.&lt;br /&gt;
|-&lt;br /&gt;
|Lights (Vapor-Proof)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|16&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|The fixtures are TOGGLED FV420PO-A423-40230 (includes 2 x 4000K 23 W 3,100 lumen bulbs).  The replacement cost in 2021 is about $65 per fixture.  TOGGLED rates the bulbs for 16 years (subject to vary based on exposure and usage).  No replacement cost is given for 2036, as technology may dictate a different solution.&lt;br /&gt;
|-&lt;br /&gt;
|PA Amplifier&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|17&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$1,300&lt;br /&gt;
|The amplifier&#039;s lifespan is based upon many factors; 20 years is an educated guess.  The biggest enemies to its longevity are excessive heat, dirt infiltration, and condensation.  Keeping the amplifier cool and clean is critical.  Often amplifiers fail due to their power supply capacitors failing; these may or may not be replaceable (the unit may be serviceable).  The cost is an estimate based on the retail cost of the existing JBL CSMA 2120, plus inflation, in 2040.&lt;br /&gt;
|-&lt;br /&gt;
|Radios&lt;br /&gt;
|2013&lt;br /&gt;
|2021&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$80&lt;br /&gt;
|$95&lt;br /&gt;
|$110&lt;br /&gt;
|$120&lt;br /&gt;
|There are six Motorola MH230R FRS/GMRS radios in the clubhouse, used for grounds-wide communication.  Four radios were purchased in 2021 to match the existing two units on hand.  New &amp;quot;old stock&amp;quot; KEBT-086-C batteries were installed in 2021.  Three charging stations are used to trickle-charge the NiMH battery packs.  Based on observations in 2021, these radios are used and abused quite hard; regular replacement is assumed.  Assume a replacement cost of $80 for two radios per 5-year interval, adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;div id=&amp;quot;0001&amp;quot;&amp;gt;Roof&amp;lt;/div&amp;gt;&lt;br /&gt;
|2014&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|11&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The assumption is that the clubhouse roof was replaced in [[Club History#2014|2014]].&lt;br /&gt;
|-&lt;br /&gt;
|Steel Doors&lt;br /&gt;
|1966&lt;br /&gt;
|Unknown&lt;br /&gt;
|30&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$8,200&lt;br /&gt;
|&lt;br /&gt;
|$8,000&lt;br /&gt;
|&lt;br /&gt;
|The steel doors appear to be original to the building.  There are nine doors in total: two for the lobby exterior, two for the family restroom, three for the men&#039;s room, and two for the women&#039;s room.  It has been proposed to replace the two exterior restroom doors and the interior men&#039;s room door as soon as possible.  Then, replace the two doors between the men&#039;s and women&#039;s room and lobby in five years or less.  The other exterior and interior doors may need to be replaced in 10-15 years.  Costs are based on estimates received in 2023.&lt;br /&gt;
|-&lt;br /&gt;
|Showers&lt;br /&gt;
|TBD&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Soffit&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The wooden soffit is in disrepair and needs replacement with a low-maintenance product.  The venting grate is failing and has allowed animal intrusion.  The replacement should coincide with gutter (and possible fascia) replacement.  No estimates have been made at this point.&lt;br /&gt;
|-&lt;br /&gt;
|Toilets&lt;br /&gt;
|TBD&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The installation date of the toilets is not known.  NOTE: Toilet valves are a separate topic.&lt;br /&gt;
|-&lt;br /&gt;
|Toilet Valves&lt;br /&gt;
|1966&lt;br /&gt;
|2021&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|3&lt;br /&gt;
|$1,100&lt;br /&gt;
|$1,300&lt;br /&gt;
|$1,400&lt;br /&gt;
|$1,600&lt;br /&gt;
|Numerous toilet valves were replaced in 2021.  Some additional refurbishment in 2022 (this is an annual need).  Rebuild kits may work; replacement is suggested after numerous rebuilds.&lt;br /&gt;
|-&lt;br /&gt;
|UPS Batteries (Front Desk)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$30&lt;br /&gt;
|$30&lt;br /&gt;
|$40&lt;br /&gt;
|$40&lt;br /&gt;
|The front desk battery backup is an APC Back-UPS XS 1500.  It uses two [https://www.power-sonic.com/product/ps-1270/ PS-1270] lead-acid batteries (the replacement cost for the Power Sonic brand is $13 each from a local distributor).&lt;br /&gt;
|-&lt;br /&gt;
|Windows (Exterior)&lt;br /&gt;
|1967&lt;br /&gt;
|None&lt;br /&gt;
|N/A&lt;br /&gt;
|N/A&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The exterior windows appear to be original to the facility (except for the newer exterior window in the Snack Shack).  No plans to replace.&lt;br /&gt;
|-&lt;br /&gt;
|Window Shutters&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Grounds ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=warn|text=This section was last updated in 2023 and needs to be reviewed.}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2023)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|Fence (Property Line)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Patio Sets&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Discussion of replacement of the patio sets is pending.&lt;br /&gt;
|-&lt;br /&gt;
|Parking Lot&lt;br /&gt;
|2000&lt;br /&gt;
|2020&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$14,400&lt;br /&gt;
|$16,300&lt;br /&gt;
|$18,500&lt;br /&gt;
|$20,800&lt;br /&gt;
|The asphalt parking lot was first installed in 2000.  Maintenance is necessary every 5-7 years (largely subject to weather).  Maintenance was known to have been performed in [[Club History#2015|2015]] and 2020.  Costs for 2025, 2030, 2035, and 2040 are based on the prior estimate (for 2020) with inflation.  NOTE: There has been some discussion (Spring 2023) whether a complete re-surfacing may be required?  Cost might be as high as $100k?  To be discussed further.&lt;br /&gt;
|-&lt;br /&gt;
|Picnic Tables (Plastic)&lt;br /&gt;
|2007&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|A spot check of a few tables suggests that the entire lot may have been purchased (or at least manufactured) in 2007.  Some tables are starting to fail mechanically and have been temporarily repaired.  Some of the painted metal parts are flaking/rusting.  It likely makes the most sense to start purchasing a small number of tables to begin the replacement of the worst units over time - unless there is a substantial benefit from a bulk order.  The lifespan of 20 years is based on current wear and tear.  It seems possible that within 5 years (from 2022), the condition of some tables may be approaching &amp;quot;poor&amp;quot;.  To be determined.&lt;br /&gt;
|-&lt;br /&gt;
|Picnic Tables (Wooden)&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|2021&lt;br /&gt;
|Unknown&lt;br /&gt;
|$100&lt;br /&gt;
|$110&lt;br /&gt;
|$130&lt;br /&gt;
|$150&lt;br /&gt;
|Outright replacement of the wooden picnic tables (7 on the property as of 2021) is not anticipated.  Instead, periodic wood/hardware replacement and stripping/painting should keep the tables in good working order.  Predicting maintenance costs is difficult, given the volatile cost of lumber.  Assume $100 every 5 years, adjusted for inflation.  All tables were power-washed and painted in 2021.&lt;br /&gt;
|-&lt;br /&gt;
|Play Structure&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|The present Miracle Recreation play structure (and swing sets) were installed in 2016.  Miracle recommends playground updates every 8-10 years; playgrounds can last 10-20 or more years, dependent upon weather and usage.  An estimated replacement date of 20 years is given, though the equipment may last longer.  Regular inspections must be performed.  Assume some maintenance cost within 5-10 years (from 2021).&lt;br /&gt;
|-&lt;br /&gt;
|Privacy Fence&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Installed in 2020, minor repairs in 2021.&lt;br /&gt;
|-&lt;br /&gt;
|Shed&lt;br /&gt;
|1986&lt;br /&gt;
|2021&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The shed was installed in 1986.  A new roof, siding (west side), and doors were installed in 2021.&lt;br /&gt;
|-&lt;br /&gt;
|Speakers&lt;br /&gt;
|2020&lt;br /&gt;
|-&lt;br /&gt;
|Water Gate Valve&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|40&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|37&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The prior gate valve lasted about 40 years before showing issues; it is assumed that the [[Water Gate Valve#History|new gate valve]] will have a similar lifespan.  No planned maintenance or replacement prior to 2061.&lt;br /&gt;
|-&lt;br /&gt;
|WiFi APs&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$380&lt;br /&gt;
|$420&lt;br /&gt;
|$480&lt;br /&gt;
|$540&lt;br /&gt;
|The present APs were installed in 2020 and are fully supported as of 2021.  An estimated life of 5 years is given, largely due to the likelihood that the product will go EOL by then.  2 of the 3 APs are mounted outdoors, and the 3rd exists in a non-climate-controlled building (clubhouse).  The APs are powered year-round to help drive off potential internal condensation.  Still, exposure may reduce their lifespan.  If the product is still supported after the 5-year mark (2025), and the units are functional, an evaluation of the performance vs. a replacement should be considered.  The replacement cost in 2021 is $125/ea (3 units).  A replacement cycle of 5 years is assumed (units may remain in service longer).&lt;br /&gt;
|-&lt;br /&gt;
|Volleyball Net&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|3&lt;br /&gt;
|&lt;br /&gt;
|$220&lt;br /&gt;
|$250&lt;br /&gt;
|$280&lt;br /&gt;
|The decision to purchase a more durable volleyball net in 2021 appears to have been a good one; the net held up well for the whole season (versus cheaper nets that had to be replaced sometimes multiple times per season).  A lifespan of 5 years is anticipated, as UV will eventually break down the vinyl.  The existing net is a [https://www.volleyballusa.com/hd2-heavy-duty-volleyball-net/ VolleyballUSA HD2].  The replacement cost is $200, adjusted for inflation on a 5-year interval.  &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Large Pavilion ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=warn|text=This section was last updated in 2021 and needs to be reviewed.}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Ceiling Fans&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$640&lt;br /&gt;
|&lt;br /&gt;
|The ceiling fans (2) are Home Decorators Collection Windward 68-in units (Home Depot SKU #1004794977).  The replacement cost as of 2021 is $249/ea (adjusted to $320/ea for 2030).  An estimated lifespan of 10 years is predicted (assuming proper off-season storage per B&amp;amp;G standard procedure).  An equivalent replacement should be as large as possible (i.e. 68-in diameter) and with integrated LED lighting.&lt;br /&gt;
|-&lt;br /&gt;
|Roof&lt;br /&gt;
|2008&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The roof is assumed to be original to pavilion construction in [[Club History#2008|2008]].  It was noted by a contractor performing repairs in 2021 that the shingles&#039; spacing is incorrect.  The repair was made to match the improper spacing.&lt;br /&gt;
|-&lt;br /&gt;
|Gas Grills&lt;br /&gt;
|2012&lt;br /&gt;
|2020&lt;br /&gt;
|30&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|21&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|Lifespan is a guess.  Installed in 2012.  Grills were largely rebuilt/refurbished in 2020.  Replacement parts should keep them going for the foreseeable future.  Maintenance costs are TBD.  NOTE: Additional maintenance is planned during the off-season between 2022 and 2023.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Men&#039;s Restroom ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=warn|text=This section was last updated in 2021 and needs to be reviewed.}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fans (Small)&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan (Large)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Pool ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=warn|text=This section was last updated in 2021 and needs to be reviewed.}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Anchors (Backstroke Flags)&lt;br /&gt;
|Unknown&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|Unknown&lt;br /&gt;
|$250&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are four backstroke flag anchors in the pool deck.  The two anchors at the east end of the pool have failed and need to be replaced.  An estimated cost of $250 (2021 pricing) covers the cost of materials and tool rental (no labor cost).  NOTE: All four anchors may be replaced due to possible improper placement with respect to the ends of the pool.&lt;br /&gt;
|-&lt;br /&gt;
|Anchors (Starting Block)&lt;br /&gt;
|2018&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|18&lt;br /&gt;
|-&lt;br /&gt;
|Cover&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Need to determine the expected lifetime.  No replacement is planned in the 1-5 year term.&lt;br /&gt;
|-&lt;br /&gt;
|Diving Board&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|$6,500&lt;br /&gt;
|&lt;br /&gt;
|$8,300&lt;br /&gt;
|The diving board installed in 2020 is a Duraflex 16&#039; Modified Maxiflex Model &amp;quot;B&amp;quot;.  The replacement cost is estimated at $5,000 as of 2020.  Replacement is recommended every 7-10 years, but may vary due to outdoor/seasonal use.  Regular inspection is required to identify cracks or stress marks.&lt;br /&gt;
|-&lt;br /&gt;
|Drain Grates&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Drain grates have an expiration date.  Likely to be replaced during the pool renovation (2022).&lt;br /&gt;
|-&lt;br /&gt;
|Guard Stand (West)&lt;br /&gt;
|TBD&lt;br /&gt;
|2022&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The west guard stand appears to be a [https://www.spectrumproducts.com/stimson-lifeguard-chair-5-57308/ Spectrum Aquatics Stimson Lifeguard Chair (57308)].  A rough estimate for replacement cost is about $6,400.  The rotating base for the chair was replaced in 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Guard Stand (North)&lt;br /&gt;
|1990&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|It appears that the north guard stand, made by SR Smith, was installed in 1990.  No further information is available at this time.  No planned replacement or maintenance at this time (TBD).&lt;br /&gt;
|-&lt;br /&gt;
|Guard Umbrellas&lt;br /&gt;
|-&lt;br /&gt;
|Handrails&lt;br /&gt;
|-&lt;br /&gt;
|Ladders&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|$400&lt;br /&gt;
|$450&lt;br /&gt;
|$510&lt;br /&gt;
|$570&lt;br /&gt;
|There are 5 4-step ladders in the pool.  The original date of purchase is not known.  Most of the ladders appear to be of SR Smith make, though at least one ladder is an &amp;quot;Aquatech&amp;quot;.  Replacement of whole ladders is not anticipated.  Repairs (i.e., replacement steps/bolts) may be needed periodically.  As of 2020, an SR Smith ladder step with bolts costs about $50.  Anticipate replacement of two steps and two anchors (estimated at $250 in 2020) every five years.&lt;br /&gt;
|-&lt;br /&gt;
|Lane Markers&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|A Competitor brand 4&amp;quot; 25-meter racing lane (marker) cost is about $430 as of 2021.  There are 6 lanes in the pool (requiring 5 markers).  The age and condition of the existing markers is TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Marcite&lt;br /&gt;
|1966&lt;br /&gt;
|Unknown&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$100,000&lt;br /&gt;
|&lt;br /&gt;
|$128,000&lt;br /&gt;
|&lt;br /&gt;
|Pricing subject to further review; a budgetary estimate.  The plan for 2022 replacement is being developed [[Pool Marcite#Plan for 2022|here]].  Assume some amount of marcite replacement is necessary every 10 years.&lt;br /&gt;
|-&lt;br /&gt;
|Safety Ropes&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Two safety ropes (rope floats) are present in the pool:&lt;br /&gt;
* Between the &amp;quot;kiddie pool&amp;quot; and main pool (11 ft)&lt;br /&gt;
* Between the main pool and the diving well (27 ft)&lt;br /&gt;
Ropes were replaced with all-new parts for the 2022 season.&lt;br /&gt;
|-&lt;br /&gt;
|Slides&lt;br /&gt;
|2007&lt;br /&gt;
|2020&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|$10,200&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The south slide is an [https://www.srsmith.com/en-us/products/pool-slides/turbotwister/ SR Smith TurboTwister], the north slide is an [https://www.srsmith.com/en-us/products/pool-slides/typhoon/ SR Smith Typhoon].  The replacement cost is $4,000 and $2,900 based on average 2021 online pricing.  The installation date of the existing slides is unknown; a serial number suggesting 2008 appears on the Typhoon.  Both slides show signs of deterioration (superficial cracking as of 2021) and are targeted for replacement within 5-10 years.  Epoxy patching will be used in the meantime.  The replacement cost is estimated for 2028 and includes $2,000 for labor.  The listed lifespan is an estimate and based upon this target date.&lt;br /&gt;
|-&lt;br /&gt;
|Underwater Lights&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|Varies&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$6,600&lt;br /&gt;
|$1,000&lt;br /&gt;
|$1,000&lt;br /&gt;
|$7,000&lt;br /&gt;
|The proposal to retrofit pool lights is detailed [[Lighting#2022 Retrofit Proposal|here]].  $1,000 has been added to that cost to install new Aladdin rings during 2022.  $2,000 covers potential repairs/replacements through 2036, $7,000 has been estimated to replace the LEDs (best guess lifespan is about 15 years).&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Pool Deck ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Chairs&lt;br /&gt;
|Varies&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|Some regular chairs are in need of repair/replacement.  As of the manager&#039;s last accounting in 2021, of the 29 regular chairs, 9 are in need of repair.  Numbers to be confirmed.  A plan should be formed to begin staged replacement.  Coordination with other area clubs may be cost beneficial.&lt;br /&gt;
|-&lt;br /&gt;
|Concrete&lt;br /&gt;
|1967&lt;br /&gt;
|2018&lt;br /&gt;
|30&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|Portions of the concrete pool deck presumably date back to the original installation in [[Club History#1967|1967]].  Multiple repairs and deck replacements have been made since then.  As of 2021, the most recent work appears to have occurred in [[Club History#1998|1998]], [[Club History#2017|2017]] and [[Club History#2018|2018]].  Regular future maintenance is anticipated; the cost is TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Fence&lt;br /&gt;
|2014&lt;br /&gt;
|-&lt;br /&gt;
|Funbrella&lt;br /&gt;
|TBD&lt;br /&gt;
|2022&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|A new crank mechanism from Anchor Industries (maker of the Funbrella) was purchased and installed in August 2022.  The prior crank mechanism had &amp;quot;worn out&amp;quot; its friction plate.  Further maintenance (hardware replacement) is planned for the structural portions.  The original installation date of the Funbrella is not known.&lt;br /&gt;
|-&lt;br /&gt;
|Lounges&lt;br /&gt;
|Varies&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|A significant number of the lounge chairs are in need of repair/replacement.  As of the manager&#039;s last accounting in 2021, of the 187 lounge chairs, 6 are not usable.  A significant number of the others are worn and should be replaced in the near future.  Numbers to be confirmed.  A plan should be formed to begin staged replacement.  Coordination with other area clubs may be cost beneficial.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Pump House ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=warn|text=This section was last updated in 2023 and needs to be reviewed.}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Acid Pump&lt;br /&gt;
|2017&lt;br /&gt;
|Unknown&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The acid pump is a Stenner 45M5.  The replacement cost in 2021 is about $400.&lt;br /&gt;
|-&lt;br /&gt;
|Boiler&lt;br /&gt;
|2004&lt;br /&gt;
|2022&lt;br /&gt;
|10&lt;br /&gt;
|TBD&lt;br /&gt;
|$2,500&lt;br /&gt;
|$25,000&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|It is difficult to say how long the pool heater should last.  The plan (as of 2021) is to replace in 5-10 years.  Multiple inspections and component replacements were made in 2020, 2021 and 2022.  The heat exchanger was replaced around 2011 (the exact year is not known).  It is expected that some burners may need to be replaced around 2025-2026 ($2,500 or less).  Some references indicate that the pool heater may only last 10 years, but this is subject to several variables.&lt;br /&gt;
|-&lt;br /&gt;
|Breaker Panel ([[Electrical System#Basement Panel RLP-3|RLP-3]])&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The date of installation of the breaker panel in the pump house is not known.  No immediate plans are in place to replace it.  It should be noted that it utilizes an aluminum bus bar, which is inherently incompatible with the corrosive environment in which it exists.&lt;br /&gt;
|-&lt;br /&gt;
|Chlorinator Pump&lt;br /&gt;
|2013&lt;br /&gt;
|2022&lt;br /&gt;
|15&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|$300&lt;br /&gt;
|&lt;br /&gt;
|$540&lt;br /&gt;
|&lt;br /&gt;
|The chlorinator pump appears to be original to the chlorinator install (about 2013).  The shaft seal was replaced in 2021 and again in 2022.  The faceplate seal was replaced in 2022.  Prior to that, the shaft seal (and faceplate) were replaced in 2018.  The lifespan estimate has been bumped up to 13 years, though continued periodic maintenance of seals is expected.  It is a bit difficult to judge how long it may last, as it operates at a relatively low duty cycle but is exposed to super-chlorinated water and vapors.  The existing motor is a Hayward Century SP1515-Z-1-EFTC 1.5 HP pool pump.  The estimated replacement cost is $300.  Shaft seal replacement (parts and labor) costs about $100; the seals alone are significantly cheaper.&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|&lt;br /&gt;
|$180&lt;br /&gt;
|$200&lt;br /&gt;
|$220&lt;br /&gt;
|The exhaust fan is a Dayton 10N201 (1/6 HP 1400 CFM).  The thermostat circuit has been bypassed; the fan is intended to operate 24/7 when the pool is operating.  The estimated useful life is based upon an assumption that the chemical vapors may cause premature failure.  The fan may last significantly longer.&lt;br /&gt;
|-&lt;br /&gt;
|Filter Sand&lt;br /&gt;
|2013&lt;br /&gt;
|2021&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|1&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|The pool filter tank sand was last changed in [[Club History#2013|2013]].  For an outdoor pool, this generally should be done every 10 years (which can coincide with marcite replacement).  The cost is pending.  The sand was stirred in 2021 and 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|$110&lt;br /&gt;
|$330&lt;br /&gt;
|$150&lt;br /&gt;
|The pump house fire extinguisher an Amerex model 240, filled with water and anti-freeze to suppress chemical fires.  Five-year maintenance ($100 in 2021) is due in 2026 and 2036 (installed in 2021).  Replacement ($260 in 2021) is due in 2031 (10 years).  Prices are adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Flow Meter (Bypass)&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Flow Meter (Output)&lt;br /&gt;
|-&lt;br /&gt;
|Garage Door&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|30&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|28&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|A new Ideal Door brand 8 ft x 7 ft white insulated (R-Value 6.5) garage door was installed in 2020.  Replacement is not anticipated until around 2050.  The replacement cost (in 2021 dollars) is about $400, excluding the cost of additional materials (hardware, trim, etc).  &lt;br /&gt;
|-&lt;br /&gt;
|GFCI Switches &lt;br /&gt;
|None&lt;br /&gt;
|2020&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|$220&lt;br /&gt;
|&lt;br /&gt;
|$290&lt;br /&gt;
|The GFCI switches in the pump house (also referred to as &amp;quot;dead front GFCI outlets&amp;quot;) are used for the pool lights, outdoor receptacles, and motor disconnects in the pump house.  A total of 9 Legrand 2087WCC4 were installed from 2020-2021.  This does not include 5 standard GFCI receptacles (tracked elsewhere).  GFCIs are said to last 10 years - but these units may last a significantly shorter period due to the corrosive environment in which they are installed.  &amp;lt;b&amp;gt;These GFCI devices in particular MUST be regularly tested as they provide critical protection to pool occupants.&amp;lt;/b&amp;gt;  The 2021 replacement cost for each is approximately $20 (may find for less in bulk or as a surplus buy).&lt;br /&gt;
|-&lt;br /&gt;
|Motor (Main Pump)&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|&lt;br /&gt;
|$1,700&lt;br /&gt;
|&lt;br /&gt;
|$2,200&lt;br /&gt;
|The main pump motor is a 15 HP 230 VAC unit, as detailed [[Pool Main Pump Motor|here]].&lt;br /&gt;
|-&lt;br /&gt;
|Pump (Main)&lt;br /&gt;
|1995&lt;br /&gt;
|Unknown&lt;br /&gt;
|30&lt;br /&gt;
|Unknown&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The installation date of the pump is not known; estimated to be from the mid-&#039;90s based on word of mouth.  The impeller and seals should be replaced every 20-40 years; it is likely due for maintenance soon.&lt;br /&gt;
|-&lt;br /&gt;
|Pump (Slide)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|The slide pump is a Grundfos Alpha1 15-55SF/LC (99287250) stainless steel circulation pump (1/16 HP).  The replacement (an Alpha2 15-55SF/LC, 99163972) is about $315 in 2021 (may be cheaper on surplus).  Circulation pumps are cited to last 10 years - but as always, subject to environment and use.&lt;br /&gt;
|-&lt;br /&gt;
|Piping (Post Pump)&lt;br /&gt;
|2021&lt;br /&gt;
|-&lt;br /&gt;
|Piping (Pre Pump)&lt;br /&gt;
|-&lt;br /&gt;
|Piping (Surge Tank)&lt;br /&gt;
|-&lt;br /&gt;
|Pool Vacuum&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The pool vacuum is a Power Vac Corporation Model #PV2100.  The date of manufacture and estimated lifespan are still TBD.  The replacement cost is about $900 in 2021.  Consider a PV2200 when replacement is due?&lt;br /&gt;
|-&lt;br /&gt;
|Pool Vacuum Battery&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Probe (pH)&lt;br /&gt;
|2022&lt;br /&gt;
|&lt;br /&gt;
|2&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$140&lt;br /&gt;
|$160&lt;br /&gt;
|$180&lt;br /&gt;
|$200&lt;br /&gt;
|Typically, the [[Chemtrol_Pool_Controller#Chemical_Probes|pH probes]] are rated to last a year.  However, with proper maintenance, [[Probe Calibration|calibration]] and off-season storage, it&#039;s assumed they&#039;ll last 2-3 years.  The cost of calibration reagent(s) is not included here, though should be considered with the chemical costs.  A new probe was installed in 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Probe (ORP)&lt;br /&gt;
|2022&lt;br /&gt;
|&lt;br /&gt;
|2&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$220&lt;br /&gt;
|$240&lt;br /&gt;
|$280&lt;br /&gt;
|$310&lt;br /&gt;
|Typically, the [[Chemtrol_Pool_Controller#Chemical_Probes|ORP probes]] are rated to last a year.  However, with proper maintenance, [[Probe Calibration|calibration]] and off-season storage, it&#039;s assumed they&#039;ll last 2-3 years.  A new probe was installed in 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Roof&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|Unknown&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|The date of installation is not known.  Repairs to the roof were made in 2021 to address a leak around the exhaust fan.  The roofer noted that 3 layers are present - this may result in added labor/disposal cost.  The roof is in serviceable condition for now (2021).  Plan on replacement in 10 years.&lt;br /&gt;
|-&lt;br /&gt;
|Sump Pump&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$300&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Surge Tank&lt;br /&gt;
|1967&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$36,800&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|As of 2021, the [[Pool_Systems_Introduction#Surge_Tank|surge tank]] is overdue for an overhaul.  The tank in its present state is &amp;quot;severely deteriorated&amp;quot;, leaking, and lacking essential functionality presumably removed via low-budget modifications.  The cost for a full overhaul is estimated at $36,800 and must be performed when the pool is empty.&lt;br /&gt;
|-&lt;br /&gt;
|Variable Frequency Drive (VFD) for Main Pump Motor&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|10&lt;br /&gt;
|&lt;br /&gt;
|$1,200&lt;br /&gt;
|&lt;br /&gt;
|$1,500&lt;br /&gt;
|The main pump motor VFD is a Yaskawa GA50U2042ABA and was installed in 2022.  The lifespan is an estimate - and is subject to many variables.  Exposure to chemical vapors (chlorine, acid) and excess heat will reduce the lifespan.  Efforts have been made to limit exposure to both.  NOTE: The VFD has been shown to reduce club energy use by about 20 % (savings of $200-$300 a month in 2022).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Snack Shack ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=warn|text=This section was last updated in 2021 and needs to be reviewed.}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Air Conditioner (Heat Pump)&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|12&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|The air conditioner (heat pump) is a single-zone, 18,000 BTU 230 V &amp;quot;mini-split&amp;quot; unit.  The indoor unit is LG p/n LSN180HEV2, and the outdoor unit is LG p/n LSU180HEV2.  Lifespan estimates place heat pumps at 10-15 years.  The replacement cost is not known.  NOTE: This unit was installed primarily to reduce the burden on the refrigeration units in the snack shack, which would often operate 24/7 during hot periods of the summer.&lt;br /&gt;
|-&lt;br /&gt;
|Drywall (Ceiling)&lt;br /&gt;
|2019&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The snack shack ceiling was replaced in 2019 due to failure (collapse).  There is no anticipated need to replace again at this time (at least not within the 20 year planning period).&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|15&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|The exhaust fan is a Broan L700.  Starting in 2022, its usefulness going forward will be greatly reduced due to the installation of the A/C unit.  &lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2019&lt;br /&gt;
|2021&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|$60&lt;br /&gt;
|$140&lt;br /&gt;
|$80&lt;br /&gt;
|$190&lt;br /&gt;
|Six-year maintenance ($38 in 2021 dollars) is due in 2025 and 2031.  Replacement ($90 in 2021 dollars) is due in 2031.  Annual servicing ($6 in 2021 dollars) is required.  Prices adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Ice Cream)&lt;br /&gt;
|2012&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|10&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$1,200&lt;br /&gt;
|&lt;br /&gt;
|The &amp;quot;Blue Bunny Ice Cream&amp;quot; freezer is a model 46SLC-LH-MFB, built in 2012.  The replacement cost is estimated to be $900 (an Avantco DFC16-HCL in 2021 dollars, adjusted for inflation in 2032).  Past experience during a power outage suggests that these units are not particularly well insulated.  A better replacement may be desired when the 20 year estimated lifespan (2032) arrives.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Upright)&lt;br /&gt;
|2014&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|12&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|$4,100&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a Supera F1R-1, DOM: 30-Mar-2014.  Last checked out by a refrigeration contractor in 2021.  The Supera brand is not well known/respected and may not last within the typical 15-20 year lifespan cited for commercial kitchen refrigeration units.  Repair parts may not be available (Supera appears to be defunct).  The estimated replacement cost is based upon an equivalent True unit.&lt;br /&gt;
|-&lt;br /&gt;
|Garbage Disposal&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|The installation date of the garbage disposal is not known at this time.&lt;br /&gt;
|-&lt;br /&gt;
|Microwave #1&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|$500&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a Sunbeam SGB8901.  This is a residential unit, and is over-stressed by high duty cycle use.  The average residential microwave is said to last 7 years - the estimate has been reduced to 5 as an estimate per the part-time heavy use.  The estimated replacement cost is based upon the purchase of a commercial microwave, better suited for the purpose.&lt;br /&gt;
|-&lt;br /&gt;
|Microwave #2&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|$500&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a Samsung MS11K3000AS.  This is a residential unit, and is over-stressed by high duty cycle use.  The average residential microwave is said to last 7 years - the estimate has been reduced to 5 as an estimate per the part-time heavy use.  The estimated replacement cost is based upon the purchase of a commercial microwave, better suited for the purpose.&lt;br /&gt;
|-&lt;br /&gt;
|Refrigerator&lt;br /&gt;
|1997&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$500&lt;br /&gt;
|$500&lt;br /&gt;
|$4,600&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a True T-23, DOM: 1-May-1997.  Last checked out by a refrigeration contractor in 2021.  Setting aside $500 in 1-5 years and $500 in 5-10 years for repairs, replacement with another a True unit in 10-15 (unit will be nearly 40 years old).  No known issues with the existing unit other than it is 24 years old (as of 2021), exceeding the expected lifespan.  That said - given the seasonal use, it may last longer.  A True unit is highly repairable (as long as the fundamentals such as the cabinet are sound).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Women&#039;s Restroom ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=warn|text=This section was last updated in 2021 and needs to be reviewed.}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fans (Small)&lt;br /&gt;
|Unknown&lt;br /&gt;
|N/A&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are two small exhaust fans in the women&#039;s restroom.  The larger of the two (13&amp;quot; assumed) is missing, the smaller (9&amp;quot; assumed) is in place, but non-functional (motor seized).  Replacement is recommended as soon as the budget permits (cost to be determined).&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan (Large)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The exhaust fan in the women&#039;s restroom is in poor condition.  Replacement is recommended as soon as the budget permits (cost to be determined).&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Asset_Registry&amp;diff=1767</id>
		<title>Asset Registry</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Asset_Registry&amp;diff=1767"/>
		<updated>2025-01-04T13:06:58Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Asset Registry is maintained by Building &amp;amp; Grounds and reviewed by the board.  The original version was created by Sally Duffy and the 2020 Capital Assessment Committee.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Last Updated:&amp;lt;/b&amp;gt; January 4th, 2025&lt;br /&gt;
&lt;br /&gt;
Where possible, inflation is considered (using [https://smartasset.com/investing/inflation-calculator this calculator], for instance).  Future investment is a &amp;quot;best guess&amp;quot; based upon past quotes or work, where possible.  NOTE: A higher-than-expected inflation rate took effect in 2022.  This has not necessarily been factored into calculations (August 2022).  Many estimates were made in 2020 and 2021.&lt;br /&gt;
&lt;br /&gt;
Columns for &amp;lt;b&amp;gt;Failure Mode and Effect Analysis (FMEA)&amp;lt;/b&amp;gt; were added in January 2023.  The columns are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Severity (S):&amp;lt;/b&amp;gt; 1 = insignificant (minimal operational impact); 10 = catastrophic (the club cannot operate)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Occurrence (O):&amp;lt;/b&amp;gt; 1 = extremely unlikely; 10 = inevitable&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Detection (D):&amp;lt;/b&amp;gt; 1 = certain to detect; 10 = certain not to detect&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Risk Priority Number (RPN):&amp;lt;/b&amp;gt; The product of O, S and D.  0 = low risk; 1000 = highest risk&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FMEA Values are subjective.  The threshold of concern (for the RPN) is generally set to 200, though subject to revision.&lt;br /&gt;
&lt;br /&gt;
== Basement ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable mw-collapsible&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|FMEA&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2025)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
!S&lt;br /&gt;
!O&lt;br /&gt;
!D&lt;br /&gt;
!RPN&lt;br /&gt;
|-&lt;br /&gt;
|Aquastat&lt;br /&gt;
|2024&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|19&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$500&lt;br /&gt;
|3&lt;br /&gt;
|2&lt;br /&gt;
|3&lt;br /&gt;
|18&lt;br /&gt;
|A Honeywell T775A2009 aquastat (electronic temperature control) was installed on the hot water circulator pump to prevent thermal run-away and support immediate hot water at the sinks and showers.&lt;br /&gt;
|-&lt;br /&gt;
|Breaker Panel ([[Electrical System#Basement Panel RLP-2|RLP-2]])&lt;br /&gt;
|1966&lt;br /&gt;
|2020&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|10&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|100&lt;br /&gt;
|The basement breaker panel is a Square D QO series (copper bus bar).  It is in good operating condition.  No plans to replace it for the foreseeable future.  The wiring was cleaned up and the branch side lugs were properly torqued in 2020.  New circuits added.  Very limited capacity left - additional circuits should be added to the upstairs panel (RLP-1).&lt;br /&gt;
|-&lt;br /&gt;
|Circulator Pump (Hot Water)&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|6&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$420&lt;br /&gt;
|&lt;br /&gt;
|3&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|75&lt;br /&gt;
|The hot water circulator pump is a Grundfos Alpha2 15-55SFC (99163937) stainless steel circulation pump (1/16 HP).  The replacement cost is $330 in 2021 (maybe cheaper on surplus).  Circulation pumps are cited to last ten years - but as always, subject to environment and use.  As of 2021, it was noted that the circulation function didn&#039;t really work correctly.  In 2024, an aquastat was added to (finally) address the issues.&lt;br /&gt;
|-&lt;br /&gt;
|Dehumidifier &amp;quot;A&amp;quot;&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|0&lt;br /&gt;
|$330&lt;br /&gt;
|$380&lt;br /&gt;
|$420&lt;br /&gt;
|$480&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|3&lt;br /&gt;
|192&lt;br /&gt;
|The existing model is a Toshiba TDDP5012ES2 50pint/day unit (DOM: 08/2019, but not placed into service until 2020).  The replacement cost is $300.  Dehumidifiers tend to be short-lived (especially in high humidity, high-duty cycle environments).  It is estimated that this unit may only last five years.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;B&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; While the severity of a failure is high (mold growth, if not resolved), this unit is easily replaceable and poses no risk to the operating status of the club.&lt;br /&gt;
|-&lt;br /&gt;
|Dehumidifier &amp;quot;B&amp;quot;&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|1&lt;br /&gt;
|$340&lt;br /&gt;
|$380&lt;br /&gt;
|$430&lt;br /&gt;
|$490&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|3&lt;br /&gt;
|192&lt;br /&gt;
|The existing model is a Frigidaire (Electrolux) FGAC7044U101 (DOM: 01/2019, but not placed into service until 2021).  The replacement cost is $300.  See the comments for &amp;lt;b&amp;gt;Dehumidifier &amp;quot;A&amp;quot;&amp;lt;/b&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|6&lt;br /&gt;
|$30&lt;br /&gt;
|$180&lt;br /&gt;
|$40&lt;br /&gt;
|$230&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The basement fire extinguisher is a Buckeye ABC unit (exact model TBD).  Six-year maintenance ($38 in 2021 dollars) is due in 2027 and 2037 (was originally due in 2023 per manufacture date but occurred in 2021).  Replacement ($90 in 2021 dollars) is due in 2029 and 2041.  Annual servicing ($6 in 2021 dollars) is required.  Prices are adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Foundation/Walls&lt;br /&gt;
|1966&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|18&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|$16,000&lt;br /&gt;
|7&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|175&lt;br /&gt;
|Installed a new internal weeping tile system and sump pump in 2021.  Assume that after 20 years, the system may need to be replaced (again) due to the eventual infiltration of sediment.  Painted basement walls with Liquid Rubber and Drylok in 2021.  Hydrostatic pressure is causing a bulge on the east wall (near the staircase).  TBD cost to address in the 5-10 year window (as of 2021) unless movement/cracking makes the project more urgent.  As of 2022, some breakdown is visible in the corners (discoloration, visible water).  This may be corrected on a spot basis.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Chest)&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|20&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|8&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|32&lt;br /&gt;
|The existing model is a Kelvinator Commercial KCCF170WH (59 1/2&amp;quot;, 17 cu ft capacity).  The date of manufacture is not known.  The replacement cost in 2021 is about $930.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Chest)&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|14&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$1,300&lt;br /&gt;
|8&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|32&lt;br /&gt;
|The existing model is an Electrolux KCCF160QWA commercial freezer (15.58 cu ft capacity).  This model does not appear to be made anymore; replacement with a KCCF170WH or equivalent (replacement cost in 2021 is about $930; about $1,300 in 2036 with inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Upright)&lt;br /&gt;
|2013&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|11&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|8&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|32&lt;br /&gt;
|The existing model is a Whirlpool EV161NZTQ02 household freezer.  The replacement cost is not known at this time.&lt;br /&gt;
|-&lt;br /&gt;
|Main Distribution Panel&lt;br /&gt;
|1966&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|10&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|100&lt;br /&gt;
|The distribution panel was informally inspected in 2021.  No signs of issues.  No plans for service or replacement soon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;B&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; Regular inspections are required.&lt;br /&gt;
|-&lt;br /&gt;
|Network Equipment&lt;br /&gt;
|2024&lt;br /&gt;
|2024&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|5&lt;br /&gt;
|3&lt;br /&gt;
|2&lt;br /&gt;
|30&lt;br /&gt;
|Some equipment replacement is anticipated every five years due to product end-of-life (EOL), failures, or technology upgrades.  The cost is not known at this time.  A new PoE network switch was installed in the clubhouse in 2022 and again in 2024.  NOTE: For the sake of security, specifics about the network are not posted on the Wiki.&lt;br /&gt;
|-&lt;br /&gt;
|Sump Pump&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$300&lt;br /&gt;
|&lt;br /&gt;
|7&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|175&lt;br /&gt;
|The sump pump is a Foundation Systems of Michigan (FSM) Elite 365 AquaStop Sump Pump System (1/3 HP).  Replacement after ten years is anticipated.&lt;br /&gt;
|-&lt;br /&gt;
|Tempering Valve&lt;br /&gt;
|2020&lt;br /&gt;
|2021&lt;br /&gt;
|8&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|6&lt;br /&gt;
|&lt;br /&gt;
|$5,300&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|50&lt;br /&gt;
|The tempering valve is a Powers LFMM 433-13 (1-1/4&amp;quot; 110 GPM).  This part number (as written in the plumbing invoice) needs to be confirmed; the -13 suffix doesn&#039;t seem to align with an actual part number.  Tempering valves are cited to last 5-8 years in general.  The impact of seasonal use is TBD.  As of 2021, the functionality of the tempering valve and its interaction with the hot water circulation pump has been problematic.  An additional effort may be required in 2022.  The temperature/pressure gauge failed in 2021 and was replaced with a Watts WLFDPTG330200D.  The material and labor cost in 2020 was about $5,300; replacement in 2028 adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|UPS Batteries (Network)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$60&lt;br /&gt;
|$70&lt;br /&gt;
|$80&lt;br /&gt;
|$90&lt;br /&gt;
|3&lt;br /&gt;
|6&lt;br /&gt;
|3&lt;br /&gt;
|54&lt;br /&gt;
|The network battery backup is an APC Smart-UPS SMC1500-2U.  It uses four [https://www.power-sonic.com/product/ps-1270/ PS-1270] lead-acid batteries (the replacement cost for the Power-Sonic brand is $13 each from a local distributor).&lt;br /&gt;
|-&lt;br /&gt;
|Water Heater&lt;br /&gt;
|2007&lt;br /&gt;
|2018&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$20,000&lt;br /&gt;
|&lt;br /&gt;
|$27,000&lt;br /&gt;
|&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|512&lt;br /&gt;
|The [domestic hot] water heater is confirmed to have been installed in 2007, both by the serial number and the permit pulled noted in [[Club History#2007|club history]].  The existing unit is a Lochinvar TNR200-100 (100-gallon) fully condensing water heater.  The standard &amp;quot;rule of thumb&amp;quot; is to pre-emptively replace a water heater at the 10-year mark.  However, the fact that the water heater is drained and dormant from about September to April should have some longevity benefits.  Replacement is assumed to be necessary within the 5-10 year span (as of 2021), if not earlier.  The replacement cost is based on a quote received for labor and materials in early 2023.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; It is assumed that the domestic hot water heater is critical to club operation (for health code reasons), and the club cannot operate without it.  Detecting a failure is difficult (water heaters often fail with little to no warning once they cross the decade-old mark).  Failure is more or less &amp;quot;inevitable&amp;quot; for a residential-grade unit.  It&#039;s not clear how the commercial-grade unit differs.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* The Freezer (Ice Cream) - &amp;quot;Blue Bunny Ice Cream&amp;quot; freezer is a model RIO S125, built in 2010 - was removed from service in 2023 (or 2024?) after identifying it had failed.&lt;br /&gt;
&lt;br /&gt;
== Basketball and Tennis Courts ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|FMEA&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2023)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
!S&lt;br /&gt;
!O&lt;br /&gt;
!D&lt;br /&gt;
!RPN&lt;br /&gt;
|-&lt;br /&gt;
|Basketball Poles&lt;br /&gt;
|2018&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|20&lt;br /&gt;
|Lifespan, replacement plans, and replacement cost are TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Surface (Basketball)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|$38,000&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are essentially four options given the court conditions:&lt;br /&gt;
# Powerwash to clean.  Fill cracks with acrylic crack filler, then resurface and paint for about $20,000.  Based on just short of 900 ft of cracks at 2020 pricing.  This is a very short-term solution; assume cracks will re-appear after a large day/night temperature swing (and especially after a freeze/thaw).  For that reason, this repair is not recommended.&lt;br /&gt;
# The same as the prior option, plus fabric overlay crack repair (2-year guarantee) for about $33,000.  This solution should last 4-5 years (after which cracks may re-appear).  This may be the best solution for the near term.  For this option, the sport coating contractor may be hired directly.&lt;br /&gt;
# Grind down 2 inches of the surface, then re-build for about $100,000 ($50,000 per court).  For this option, hire a paving contractor; the sport coating is subcontracted.&lt;br /&gt;
# Demolish, add improved drainage, then rebuild for about $150,000 ($75,000 per court).  This is by far the most expensive, but the most effective solution depending upon the underlying issues (i.e. very wet grounds).  For this option, hire a paving contractor; the sport coating is subcontracted.&lt;br /&gt;
Given current budgets, it seems likely that option #2 is the best choice for the 5-10 year window.  The lifespan of 5 years assumes repeated use of option #2.&lt;br /&gt;
|-&lt;br /&gt;
|Surface (Tennis)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|$42,000&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are essentially four options given the court conditions:&lt;br /&gt;
# Powerwash to clean.  Fill cracks with acrylic crack filler, then resurface and paint per USTA standards for about $23,000.  Based on just short of 1000 ft of cracks at 2020 pricing.  This is a very short-term solution; assume cracks will re-appear after a large day/night temperature swing (and especially after a freeze/thaw).  For that reason, this repair is not recommended.&lt;br /&gt;
# The same as the prior option, plus fabric overlay crack repair (2-year guarantee) for about $37,000.  This solution should last 4-5 years (after which cracks may re-appear).  This may be the best solution for the near term.  For this option, the sport coating contractor may be hired directly.&lt;br /&gt;
# Grind down 2 inches of the surface, then re-build for about $100,000 ($50,000 per court).  For this option, hire a paving contractor; the sport coating is sub-contracted.&lt;br /&gt;
# Demolish entirely, add improved drainage, then re-build for about $150,000 ($75,000 per court).  This is by far the most expensive, but the most effective solution depending upon the underlying issues (i.e. very wet grounds).  For this option, hire a paving contractor; the sport coating is sub-contracted.&lt;br /&gt;
Given present budgets, it seems likely that option #2 is the best choice for the 5-10 year window.  The lifespan of 5 years assumes repeated use of option #2.&lt;br /&gt;
|-&lt;br /&gt;
|Tennis Nets&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|New Edwards 30LS &amp;quot;Wimbledon Nets&amp;quot; were purchased in late 2021 and installed in the spring of 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Tennis Pole Hardware&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|$150&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The age of the existing poles is not known.  In 2022, two new &amp;quot;53420-B EZ Tennis Post Replacement Reels&amp;quot; from &amp;quot;Tennis Court Supply&amp;quot; were installed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Clubhouse ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2023)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|Awning&lt;br /&gt;
|1997&lt;br /&gt;
|2020&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|It appears (but has not been confirmed) that the awning was installed in 1997.  The fabric material is assumed to be Sunbrella, with a 10-year rated lifespan.  However, 24 years later (as of 2021), it still looks good.  The fabric was cleaned per manufacturer recommendations in 2020.  No planned replacement until it is aesthetically necessary.&lt;br /&gt;
|-&lt;br /&gt;
|Breaker Panel ([[Electrical System#Basement Panel RLP-1|RLP-1]])&lt;br /&gt;
|2007&lt;br /&gt;
|2022&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The &amp;quot;upstairs&amp;quot; panel was added in [[Club History#2007|2007]] presumably to support additional circuits (hand dryers, etc).  There are no plans to replace it in the 20-year window.  The panel was last serviced in 2022.  Lug torques were verified, and new circuits were added.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; Regular inspections are required to meet the &amp;quot;detection&amp;quot; value.&lt;br /&gt;
|-&lt;br /&gt;
|Changing Table&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|17&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The baby changing station is a Koala Kare KB200 (replacement cost is $210 based on average online pricing as of 2021).  The lifespan is a guess and may be adjusted depending on observations of wear and tear in future years.  There is no planned replacement within the 20-year window (as of 2023).&lt;br /&gt;
|-&lt;br /&gt;
|Chimney&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The chimney is most likely original to the 1966 structure.  It is functionally obsolete; the only device producing combustion gases in the clubhouse is vented via PVC pipe.  Unfortunately, the mortar appears to be failing.  Tuckpointing is recommended shortly.  Alternatively, the chimney could potentially be removed.&lt;br /&gt;
|-&lt;br /&gt;
|Computer&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|3&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|A regular refresh cycle for the front-desk computer is planned.  The replacement cost is TBD (donated/retired business PCs preferred).&lt;br /&gt;
|-&lt;br /&gt;
|Drywall (Family Restroom Ceiling)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The family restroom ceiling was replaced in 2020 upon discovery that it was sagging several inches in the middle of the room.  No replacement is planned.&lt;br /&gt;
|-&lt;br /&gt;
|Drywall (Lobby Ceiling)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Repairs were made to the drywall near the north end (to address sagging) during the 2022 lobby renovation.  At this time, it was observed that repairs had previously been made near the &amp;quot;Fairway Farms&amp;quot; glass by the stairs.  No replacement is planned.&lt;br /&gt;
|-&lt;br /&gt;
|Electrical&lt;br /&gt;
|1966&lt;br /&gt;
|2020&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|7&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&amp;lt;p&amp;gt;Much of the wiring in the clubhouse is original to the 1966 installation.  Fortunately, #12 AWG copper was run in rigid conduit throughout.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;In 2020, the wiring was inspected and found in good condition.  Nearly all receptacles, switches, and fixtures were replaced.  All associated connections (screws, wire nuts) were removed, cleaned of oxidation, and re-terminated.  Wiring in panels ([[Electrical System#Basement Panel RLP-1|RLP-1]] and [[Electrical System#Basement Panel RLP-2|RLP-2]]) was cleaned up, and all branch-side lugs were torqued to spec.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;The basement switchgear was inspected and deemed to be in good operating condition (no replacement planned).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Replacement of certain receptacles, switches, and fixtures may be needed on a 10-year interval.  The cost is TBD.&amp;lt;/p&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Exit Signs&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$80&lt;br /&gt;
|$90&lt;br /&gt;
|$100&lt;br /&gt;
|$120&lt;br /&gt;
|The lifespan of the two exit signs is largely determined by the ability of the internal rechargeable batteries to sustain 90 minutes of illumination upon power failure.  This is an annual city inspection requirement (Livonia Code of Ordinances 15.32.030).  The battery pack may be replaceable.  If not, off-brand exit signs with floodlights can be had for as little as $40 (or less) on Amazon.&lt;br /&gt;
|-&lt;br /&gt;
|Fans (Pedestal)&lt;br /&gt;
|1995&lt;br /&gt;
|None&lt;br /&gt;
|50&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|22&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are two pedestal fans in the clubhouse.  One appears to be from 1995; the date of manufacture for the other is unknown (TBD).  The fans are anticipated to last beyond the 20-year view (as of 2021). Minor repairs may be needed; the cost is TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2016&lt;br /&gt;
|2020&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|$70&lt;br /&gt;
|$140&lt;br /&gt;
|$80&lt;br /&gt;
|$180&lt;br /&gt;
|The clubhouse (lobby) fire extinguisher is an Advantage ADV-10, as of 2021, last serviced in May 2020 (per punch tag).  Six-year maintenance ($38 in 2021 dollars) is assumed to be due in 2022 and 2034. Replacement ($90 in 2021 dollars) is due in 2028 and 2040. Annual servicing ($6 in 2021 dollars) is required. Prices are adjusted for inflation. &lt;br /&gt;
|-&lt;br /&gt;
|Floor&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Any rehabilitation or replacement of the floor in the clubhouse (main floor) is yet to be discussed.  The original installation date is not known.&lt;br /&gt;
|-&lt;br /&gt;
|Gutters&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Gutters are in disrepair (leaking) and should be replaced.  The plan is for the 5-10 year window (as of 2021).  We received quotes in 2020 that need to be located for reference.&lt;br /&gt;
|-&lt;br /&gt;
|Hand Dryers&lt;br /&gt;
|2007&lt;br /&gt;
|None&lt;br /&gt;
|25&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|The existing American Dryer (Global Dryer) model GX1 units were installed in [[Club_History#2007|2007]].  Lifespan is a guess.  The estimated cost is for two replacement units in 2032 ($150/ea in 2021 prices).  Labor is not included.&lt;br /&gt;
|-&lt;br /&gt;
|Lights (Vapor-Proof)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|16&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|The fixtures are TOGGLED FV420PO-A423-40230 (includes 2 x 4000K 23 W 3,100 lumen bulbs).  The replacement cost in 2021 is about $65 per fixture.  TOGGLED rates the bulbs for 16 years (subject to vary based on exposure and usage).  No replacement cost is given for 2036, as technology may dictate a different solution.&lt;br /&gt;
|-&lt;br /&gt;
|PA Amplifier&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|17&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$1,300&lt;br /&gt;
|The amplifier&#039;s lifespan is based upon many factors; 20 years is an educated guess.  The biggest enemies to its longevity are excessive heat, dirt infiltration, and condensation.  Keeping the amplifier cool and clean is critical.  Often amplifiers fail due to their power supply capacitors failing; these may or may not be replaceable (the unit may be serviceable).  The cost is an estimate based on the retail cost of the existing JBL CSMA 2120, plus inflation, in 2040.&lt;br /&gt;
|-&lt;br /&gt;
|Radios&lt;br /&gt;
|2013&lt;br /&gt;
|2021&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$80&lt;br /&gt;
|$95&lt;br /&gt;
|$110&lt;br /&gt;
|$120&lt;br /&gt;
|There are six Motorola MH230R FRS/GMRS radios in the clubhouse, used for grounds-wide communication.  Four radios were purchased in 2021 to match the existing two units on hand.  New &amp;quot;old stock&amp;quot; KEBT-086-C batteries were installed in 2021.  Three charging stations are used to trickle-charge the NiMH battery packs.  Based on observations in 2021, these radios are used and abused quite hard; regular replacement is assumed.  Assume a replacement cost of $80 for two radios per 5-year interval, adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;div id=&amp;quot;0001&amp;quot;&amp;gt;Roof&amp;lt;/div&amp;gt;&lt;br /&gt;
|2014&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|11&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The assumption is that the clubhouse roof was replaced in [[Club History#2014|2014]].&lt;br /&gt;
|-&lt;br /&gt;
|Steel Doors&lt;br /&gt;
|1966&lt;br /&gt;
|Unknown&lt;br /&gt;
|30&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$8,200&lt;br /&gt;
|&lt;br /&gt;
|$8,000&lt;br /&gt;
|&lt;br /&gt;
|The steel doors appear to be original to the building.  There are nine doors in total: two for the lobby exterior, two for the family restroom, three for the men&#039;s room, and two for the women&#039;s room.  It has been proposed to replace the two exterior restroom doors and the interior men&#039;s room door as soon as possible.  Then, replace the two doors between the men&#039;s and women&#039;s room and lobby in five years or less.  The other exterior and interior doors may need to be replaced in 10-15 years.  Costs are based on estimates received in 2023.&lt;br /&gt;
|-&lt;br /&gt;
|Showers&lt;br /&gt;
|TBD&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Soffit&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The wooden soffit is in disrepair and needs replacement with a low-maintenance product.  The venting grate is failing and has allowed animal intrusion.  The replacement should coincide with gutter (and possible fascia) replacement.  No estimates have been made at this point.&lt;br /&gt;
|-&lt;br /&gt;
|Toilets&lt;br /&gt;
|TBD&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The installation date of the toilets is not known.  NOTE: Toilet valves are a separate topic.&lt;br /&gt;
|-&lt;br /&gt;
|Toilet Valves&lt;br /&gt;
|1966&lt;br /&gt;
|2021&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|3&lt;br /&gt;
|$1,100&lt;br /&gt;
|$1,300&lt;br /&gt;
|$1,400&lt;br /&gt;
|$1,600&lt;br /&gt;
|Numerous toilet valves were replaced in 2021.  Some additional refurbishment in 2022 (this is an annual need).  Rebuild kits may work; replacement is suggested after numerous rebuilds.&lt;br /&gt;
|-&lt;br /&gt;
|UPS Batteries (Front Desk)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$30&lt;br /&gt;
|$30&lt;br /&gt;
|$40&lt;br /&gt;
|$40&lt;br /&gt;
|The front desk battery backup is an APC Back-UPS XS 1500.  It uses two [https://www.power-sonic.com/product/ps-1270/ PS-1270] lead-acid batteries (the replacement cost for the Power Sonic brand is $13 each from a local distributor).&lt;br /&gt;
|-&lt;br /&gt;
|Windows (Exterior)&lt;br /&gt;
|1967&lt;br /&gt;
|None&lt;br /&gt;
|N/A&lt;br /&gt;
|N/A&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The exterior windows appear to be original to the facility (except for the newer exterior window in the Snack Shack).  No plans to replace.&lt;br /&gt;
|-&lt;br /&gt;
|Window Shutters&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Grounds ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2023)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|Fence (Property Line)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Patio Sets&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Discussion of replacement of the patio sets is pending.&lt;br /&gt;
|-&lt;br /&gt;
|Parking Lot&lt;br /&gt;
|2000&lt;br /&gt;
|2020&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$14,400&lt;br /&gt;
|$16,300&lt;br /&gt;
|$18,500&lt;br /&gt;
|$20,800&lt;br /&gt;
|The asphalt parking lot was first installed in 2000.  Maintenance is necessary every 5-7 years (largely subject to weather).  Maintenance was known to have been performed in [[Club History#2015|2015]] and 2020.  Costs for 2025, 2030, 2035, and 2040 are based on the prior estimate (for 2020) with inflation.  NOTE: There has been some discussion (Spring 2023) whether a complete re-surfacing may be required?  Cost might be as high as $100k?  To be discussed further.&lt;br /&gt;
|-&lt;br /&gt;
|Picnic Tables (Plastic)&lt;br /&gt;
|2007&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|A spot check of a few tables suggests that the entire lot may have been purchased (or at least manufactured) in 2007.  Some tables are starting to fail mechanically and have been temporarily repaired.  Some of the painted metal parts are flaking/rusting.  It likely makes the most sense to start purchasing a small number of tables to begin the replacement of the worst units over time - unless there is a substantial benefit from a bulk order.  The lifespan of 20 years is based on current wear and tear.  It seems possible that within 5 years (from 2022), the condition of some tables may be approaching &amp;quot;poor&amp;quot;.  To be determined.&lt;br /&gt;
|-&lt;br /&gt;
|Picnic Tables (Wooden)&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|2021&lt;br /&gt;
|Unknown&lt;br /&gt;
|$100&lt;br /&gt;
|$110&lt;br /&gt;
|$130&lt;br /&gt;
|$150&lt;br /&gt;
|Outright replacement of the wooden picnic tables (7 on the property as of 2021) is not anticipated.  Instead, periodic wood/hardware replacement and stripping/painting should keep the tables in good working order.  Predicting maintenance costs is difficult, given the volatile cost of lumber.  Assume $100 every 5 years, adjusted for inflation.  All tables were power-washed and painted in 2021.&lt;br /&gt;
|-&lt;br /&gt;
|Play Structure&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|The present Miracle Recreation play structure (and swing sets) were installed in 2016.  Miracle recommends playground updates every 8-10 years; playgrounds can last 10-20 or more years, dependent upon weather and usage.  An estimated replacement date of 20 years is given, though the equipment may last longer.  Regular inspections must be performed.  Assume some maintenance cost within 5-10 years (from 2021).&lt;br /&gt;
|-&lt;br /&gt;
|Privacy Fence&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Installed in 2020, minor repairs in 2021.&lt;br /&gt;
|-&lt;br /&gt;
|Shed&lt;br /&gt;
|1986&lt;br /&gt;
|2021&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The shed was installed in 1986.  A new roof, siding (west side), and doors were installed in 2021.&lt;br /&gt;
|-&lt;br /&gt;
|Speakers&lt;br /&gt;
|2020&lt;br /&gt;
|-&lt;br /&gt;
|Water Gate Valve&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|40&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|37&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The prior gate valve lasted about 40 years before showing issues; it is assumed that the [[Water Gate Valve#History|new gate valve]] will have a similar lifespan.  No planned maintenance or replacement prior to 2061.&lt;br /&gt;
|-&lt;br /&gt;
|WiFi APs&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$380&lt;br /&gt;
|$420&lt;br /&gt;
|$480&lt;br /&gt;
|$540&lt;br /&gt;
|The present APs were installed in 2020 and are fully supported as of 2021.  An estimated life of 5 years is given, largely due to the likelihood that the product will go EOL by then.  2 of the 3 APs are mounted outdoors, and the 3rd exists in a non-climate-controlled building (clubhouse).  The APs are powered year-round to help drive off potential internal condensation.  Still, exposure may reduce their lifespan.  If the product is still supported after the 5-year mark (2025), and the units are functional, an evaluation of the performance vs. a replacement should be considered.  The replacement cost in 2021 is $125/ea (3 units).  A replacement cycle of 5 years is assumed (units may remain in service longer).&lt;br /&gt;
|-&lt;br /&gt;
|Volleyball Net&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|3&lt;br /&gt;
|&lt;br /&gt;
|$220&lt;br /&gt;
|$250&lt;br /&gt;
|$280&lt;br /&gt;
|The decision to purchase a more durable volleyball net in 2021 appears to have been a good one; the net held up well for the whole season (versus cheaper nets that had to be replaced sometimes multiple times per season).  A lifespan of 5 years is anticipated, as UV will eventually break down the vinyl.  The existing net is a [https://www.volleyballusa.com/hd2-heavy-duty-volleyball-net/ VolleyballUSA HD2].  The replacement cost is $200, adjusted for inflation on a 5-year interval.  &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Large Pavilion ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Ceiling Fans&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$640&lt;br /&gt;
|&lt;br /&gt;
|The ceiling fans (2) are Home Decorators Collection Windward 68-in units (Home Depot SKU #1004794977).  The replacement cost as of 2021 is $249/ea (adjusted to $320/ea for 2030).  An estimated lifespan of 10 years is predicted (assuming proper off-season storage per B&amp;amp;G standard procedure).  An equivalent replacement should be as large as possible (i.e. 68-in diameter) and with integrated LED lighting.&lt;br /&gt;
|-&lt;br /&gt;
|Roof&lt;br /&gt;
|2008&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The roof is assumed to be original to pavilion construction in [[Club History#2008|2008]].  It was noted by a contractor performing repairs in 2021 that the shingles&#039; spacing is incorrect.  The repair was made to match the improper spacing.&lt;br /&gt;
|-&lt;br /&gt;
|Gas Grills&lt;br /&gt;
|2012&lt;br /&gt;
|2020&lt;br /&gt;
|30&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|21&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|Lifespan is a guess.  Installed in 2012.  Grills were largely rebuilt/refurbished in 2020.  Replacement parts should keep them going for the foreseeable future.  Maintenance costs are TBD.  NOTE: Additional maintenance is planned during the off-season between 2022 and 2023.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Men&#039;s Restroom ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fans (Small)&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan (Large)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Projector&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The existing projector is a Viewsonic PJD555W (DLP 1280x800 WXGA, 20,000:1 contrast, 3,300 lumens).  It is discontinued by the manufacturer (as of 2017).  Lamp hours as of 2021 not know (lifespan is 5,000 hours).  Replacement may be desired to purchase a higher-lumen model to allow utilization before dusk (low priority).  A lifespan of 10 years has been assigned; it&#039;s assumed that by 2027, a replacement will be desired.  Movie nights in 2022 were hosted using member-provided equipment.&lt;br /&gt;
|-&lt;br /&gt;
|Projector Screen&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|This item is TBD.  Two &amp;quot;old&amp;quot; projector screens were removed and discarded in 2022.  A third (new-in-box) remains in the basement.  Movie nights in 2022 were hosted using member-provided equipment.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Pool ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Anchors (Backstroke Flags)&lt;br /&gt;
|Unknown&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|Unknown&lt;br /&gt;
|$250&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are four backstroke flag anchors in the pool deck.  The two anchors at the east end of the pool have failed and need to be replaced.  An estimated cost of $250 (2021 pricing) covers the cost of materials and tool rental (no labor cost).  NOTE: All four anchors may be replaced due to possible improper placement with respect to the ends of the pool.&lt;br /&gt;
|-&lt;br /&gt;
|Anchors (Starting Block)&lt;br /&gt;
|2018&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|18&lt;br /&gt;
|-&lt;br /&gt;
|Cover&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Need to determine the expected lifetime.  No replacement is planned in the 1-5 year term.&lt;br /&gt;
|-&lt;br /&gt;
|Diving Board&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|$6,500&lt;br /&gt;
|&lt;br /&gt;
|$8,300&lt;br /&gt;
|The diving board installed in 2020 is a Duraflex 16&#039; Modified Maxiflex Model &amp;quot;B&amp;quot;.  The replacement cost is estimated at $5,000 as of 2020.  Replacement is recommended every 7-10 years, but may vary due to outdoor/seasonal use.  Regular inspection is required to identify cracks or stress marks.&lt;br /&gt;
|-&lt;br /&gt;
|Drain Grates&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Drain grates have an expiration date.  Likely to be replaced during the pool renovation (2022).&lt;br /&gt;
|-&lt;br /&gt;
|Guard Stand (West)&lt;br /&gt;
|TBD&lt;br /&gt;
|2022&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The west guard stand appears to be a [https://www.spectrumproducts.com/stimson-lifeguard-chair-5-57308/ Spectrum Aquatics Stimson Lifeguard Chair (57308)].  A rough estimate for replacement cost is about $6,400.  The rotating base for the chair was replaced in 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Guard Stand (North)&lt;br /&gt;
|1990&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|It appears that the north guard stand, made by SR Smith, was installed in 1990.  No further information is available at this time.  No planned replacement or maintenance at this time (TBD).&lt;br /&gt;
|-&lt;br /&gt;
|Guard Umbrellas&lt;br /&gt;
|-&lt;br /&gt;
|Handrails&lt;br /&gt;
|-&lt;br /&gt;
|Ladders&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|$400&lt;br /&gt;
|$450&lt;br /&gt;
|$510&lt;br /&gt;
|$570&lt;br /&gt;
|There are 5 4-step ladders in the pool.  The original date of purchase is not known.  Most of the ladders appear to be of SR Smith make, though at least one ladder is an &amp;quot;Aquatech&amp;quot;.  Replacement of whole ladders is not anticipated.  Repairs (i.e., replacement steps/bolts) may be needed periodically.  As of 2020, an SR Smith ladder step with bolts costs about $50.  Anticipate replacement of two steps and two anchors (estimated at $250 in 2020) every five years.&lt;br /&gt;
|-&lt;br /&gt;
|Lane Markers&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|A Competitor brand 4&amp;quot; 25-meter racing lane (marker) cost is about $430 as of 2021.  There are 6 lanes in the pool (requiring 5 markers).  The age and condition of the existing markers is TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Marcite&lt;br /&gt;
|1966&lt;br /&gt;
|Unknown&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$100,000&lt;br /&gt;
|&lt;br /&gt;
|$128,000&lt;br /&gt;
|&lt;br /&gt;
|Pricing subject to further review; a budgetary estimate.  The plan for 2022 replacement is being developed [[Pool Marcite#Plan for 2022|here]].  Assume some amount of marcite replacement is necessary every 10 years.&lt;br /&gt;
|-&lt;br /&gt;
|Safety Ropes&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Two safety ropes (rope floats) are present in the pool:&lt;br /&gt;
* Between the &amp;quot;kiddie pool&amp;quot; and main pool (11 ft)&lt;br /&gt;
* Between the main pool and the diving well (27 ft)&lt;br /&gt;
Ropes were replaced with all-new parts for the 2022 season.&lt;br /&gt;
|-&lt;br /&gt;
|Slides&lt;br /&gt;
|2007&lt;br /&gt;
|2020&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|$10,200&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The south slide is an [https://www.srsmith.com/en-us/products/pool-slides/turbotwister/ SR Smith TurboTwister], the north slide is an [https://www.srsmith.com/en-us/products/pool-slides/typhoon/ SR Smith Typhoon].  The replacement cost is $4,000 and $2,900 based on average 2021 online pricing.  The installation date of the existing slides is unknown; a serial number suggesting 2008 appears on the Typhoon.  Both slides show signs of deterioration (superficial cracking as of 2021) and are targeted for replacement within 5-10 years.  Epoxy patching will be used in the meantime.  The replacement cost is estimated for 2028 and includes $2,000 for labor.  The listed lifespan is an estimate and based upon this target date.&lt;br /&gt;
|-&lt;br /&gt;
|Underwater Lights&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|Varies&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$6,600&lt;br /&gt;
|$1,000&lt;br /&gt;
|$1,000&lt;br /&gt;
|$7,000&lt;br /&gt;
|The proposal to retrofit pool lights is detailed [[Lighting#2022 Retrofit Proposal|here]].  $1,000 has been added to that cost to install new Aladdin rings during 2022.  $2,000 covers potential repairs/replacements through 2036, $7,000 has been estimated to replace the LEDs (best guess lifespan is about 15 years).&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Pool Deck ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Chairs&lt;br /&gt;
|Varies&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|Some regular chairs are in need of repair/replacement.  As of the manager&#039;s last accounting in 2021, of the 29 regular chairs, 9 are in need of repair.  Numbers to be confirmed.  A plan should be formed to begin staged replacement.  Coordination with other area clubs may be cost beneficial.&lt;br /&gt;
|-&lt;br /&gt;
|Concrete&lt;br /&gt;
|1967&lt;br /&gt;
|2018&lt;br /&gt;
|30&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|Portions of the concrete pool deck presumably date back to the original installation in [[Club History#1967|1967]].  Multiple repairs and deck replacements have been made since then.  As of 2021, the most recent work appears to have occurred in [[Club History#1998|1998]], [[Club History#2017|2017]] and [[Club History#2018|2018]].  Regular future maintenance is anticipated; the cost is TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Fence&lt;br /&gt;
|2014&lt;br /&gt;
|-&lt;br /&gt;
|Funbrella&lt;br /&gt;
|TBD&lt;br /&gt;
|2022&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|A new crank mechanism from Anchor Industries (maker of the Funbrella) was purchased and installed in August 2022.  The prior crank mechanism had &amp;quot;worn out&amp;quot; its friction plate.  Further maintenance (hardware replacement) is planned for the structural portions.  The original installation date of the Funbrella is not known.&lt;br /&gt;
|-&lt;br /&gt;
|Lounges&lt;br /&gt;
|Varies&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|A significant number of the lounge chairs are in need of repair/replacement.  As of the manager&#039;s last accounting in 2021, of the 187 lounge chairs, 6 are not usable.  A significant number of the others are worn and should be replaced in the near future.  Numbers to be confirmed.  A plan should be formed to begin staged replacement.  Coordination with other area clubs may be cost beneficial.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Pump House ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Acid Pump&lt;br /&gt;
|2017&lt;br /&gt;
|Unknown&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The acid pump is a Stenner 45M5.  The replacement cost in 2021 is about $400.&lt;br /&gt;
|-&lt;br /&gt;
|Boiler&lt;br /&gt;
|2004&lt;br /&gt;
|2022&lt;br /&gt;
|10&lt;br /&gt;
|TBD&lt;br /&gt;
|$2,500&lt;br /&gt;
|$25,000&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|It is difficult to say how long the pool heater should last.  The plan (as of 2021) is to replace in 5-10 years.  Multiple inspections and component replacements were made in 2020, 2021 and 2022.  The heat exchanger was replaced around 2011 (the exact year is not known).  It is expected that some burners may need to be replaced around 2025-2026 ($2,500 or less).  Some references indicate that the pool heater may only last 10 years, but this is subject to several variables.&lt;br /&gt;
|-&lt;br /&gt;
|Breaker Panel ([[Electrical System#Basement Panel RLP-3|RLP-3]])&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The date of installation of the breaker panel in the pump house is not known.  No immediate plans are in place to replace it.  It should be noted that it utilizes an aluminum bus bar, which is inherently incompatible with the corrosive environment in which it exists.&lt;br /&gt;
|-&lt;br /&gt;
|Chlorinator Pump&lt;br /&gt;
|2013&lt;br /&gt;
|2022&lt;br /&gt;
|15&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|$300&lt;br /&gt;
|&lt;br /&gt;
|$540&lt;br /&gt;
|&lt;br /&gt;
|The chlorinator pump appears to be original to the chlorinator install (about 2013).  The shaft seal was replaced in 2021 and again in 2022.  The faceplate seal was replaced in 2022.  Prior to that, the shaft seal (and faceplate) were replaced in 2018.  The lifespan estimate has been bumped up to 13 years, though continued periodic maintenance of seals is expected.  It is a bit difficult to judge how long it may last, as it operates at a relatively low duty cycle but is exposed to super-chlorinated water and vapors.  The existing motor is a Hayward Century SP1515-Z-1-EFTC 1.5 HP pool pump.  The estimated replacement cost is $300.  Shaft seal replacement (parts and labor) costs about $100; the seals alone are significantly cheaper.&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|&lt;br /&gt;
|$180&lt;br /&gt;
|$200&lt;br /&gt;
|$220&lt;br /&gt;
|The exhaust fan is a Dayton 10N201 (1/6 HP 1400 CFM).  The thermostat circuit has been bypassed; the fan is intended to operate 24/7 when the pool is operating.  The estimated useful life is based upon an assumption that the chemical vapors may cause premature failure.  The fan may last significantly longer.&lt;br /&gt;
|-&lt;br /&gt;
|Filter Sand&lt;br /&gt;
|2013&lt;br /&gt;
|2021&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|1&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|The pool filter tank sand was last changed in [[Club History#2013|2013]].  For an outdoor pool, this generally should be done every 10 years (which can coincide with marcite replacement).  The cost is pending.  The sand was stirred in 2021 and 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|$110&lt;br /&gt;
|$330&lt;br /&gt;
|$150&lt;br /&gt;
|The pump house fire extinguisher an Amerex model 240, filled with water and anti-freeze to suppress chemical fires.  Five-year maintenance ($100 in 2021) is due in 2026 and 2036 (installed in 2021).  Replacement ($260 in 2021) is due in 2031 (10 years).  Prices are adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Flow Meter (Bypass)&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Flow Meter (Output)&lt;br /&gt;
|-&lt;br /&gt;
|Garage Door&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|30&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|28&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|A new Ideal Door brand 8 ft x 7 ft white insulated (R-Value 6.5) garage door was installed in 2020.  Replacement is not anticipated until around 2050.  The replacement cost (in 2021 dollars) is about $400, excluding the cost of additional materials (hardware, trim, etc).  &lt;br /&gt;
|-&lt;br /&gt;
|GFCI Switches &lt;br /&gt;
|None&lt;br /&gt;
|2020&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|$220&lt;br /&gt;
|&lt;br /&gt;
|$290&lt;br /&gt;
|The GFCI switches in the pump house (also referred to as &amp;quot;dead front GFCI outlets&amp;quot;) are used for the pool lights, outdoor receptacles, and motor disconnects in the pump house.  A total of 9 Legrand 2087WCC4 were installed from 2020-2021.  This does not include 5 standard GFCI receptacles (tracked elsewhere).  GFCIs are said to last 10 years - but these units may last a significantly shorter period due to the corrosive environment in which they are installed.  &amp;lt;b&amp;gt;These GFCI devices in particular MUST be regularly tested as they provide critical protection to pool occupants.&amp;lt;/b&amp;gt;  The 2021 replacement cost for each is approximately $20 (may find for less in bulk or as a surplus buy).&lt;br /&gt;
|-&lt;br /&gt;
|Motor (Main Pump)&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|&lt;br /&gt;
|$1,700&lt;br /&gt;
|&lt;br /&gt;
|$2,200&lt;br /&gt;
|The main pump motor is a 15 HP 230 VAC unit, as detailed [[Pool Main Pump Motor|here]].&lt;br /&gt;
|-&lt;br /&gt;
|Pump (Main)&lt;br /&gt;
|1995&lt;br /&gt;
|Unknown&lt;br /&gt;
|30&lt;br /&gt;
|Unknown&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The installation date of the pump is not known; estimated to be from the mid-&#039;90s based on word of mouth.  The impeller and seals should be replaced every 20-40 years; it is likely due for maintenance soon.&lt;br /&gt;
|-&lt;br /&gt;
|Pump (Slide)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|The slide pump is a Grundfos Alpha1 15-55SF/LC (99287250) stainless steel circulation pump (1/16 HP).  The replacement (an Alpha2 15-55SF/LC, 99163972) is about $315 in 2021 (may be cheaper on surplus).  Circulation pumps are cited to last 10 years - but as always, subject to environment and use.&lt;br /&gt;
|-&lt;br /&gt;
|Piping (Post Pump)&lt;br /&gt;
|2021&lt;br /&gt;
|-&lt;br /&gt;
|Piping (Pre Pump)&lt;br /&gt;
|-&lt;br /&gt;
|Piping (Surge Tank)&lt;br /&gt;
|-&lt;br /&gt;
|Pool Vacuum&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The pool vacuum is a Power Vac Corporation Model #PV2100.  The date of manufacture and estimated lifespan are still TBD.  The replacement cost is about $900 in 2021.  Consider a PV2200 when replacement is due?&lt;br /&gt;
|-&lt;br /&gt;
|Pool Vacuum Battery&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Probe (pH)&lt;br /&gt;
|2022&lt;br /&gt;
|&lt;br /&gt;
|2&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$140&lt;br /&gt;
|$160&lt;br /&gt;
|$180&lt;br /&gt;
|$200&lt;br /&gt;
|Typically, the [[Chemtrol_Pool_Controller#Chemical_Probes|pH probes]] are rated to last a year.  However, with proper maintenance, [[Probe Calibration|calibration]] and off-season storage, it&#039;s assumed they&#039;ll last 2-3 years.  The cost of calibration reagent(s) is not included here, though should be considered with the chemical costs.  A new probe was installed in 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Probe (ORP)&lt;br /&gt;
|2022&lt;br /&gt;
|&lt;br /&gt;
|2&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$220&lt;br /&gt;
|$240&lt;br /&gt;
|$280&lt;br /&gt;
|$310&lt;br /&gt;
|Typically, the [[Chemtrol_Pool_Controller#Chemical_Probes|ORP probes]] are rated to last a year.  However, with proper maintenance, [[Probe Calibration|calibration]] and off-season storage, it&#039;s assumed they&#039;ll last 2-3 years.  A new probe was installed in 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Roof&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|Unknown&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|The date of installation is not known.  Repairs to the roof were made in 2021 to address a leak around the exhaust fan.  The roofer noted that 3 layers are present - this may result in added labor/disposal cost.  The roof is in serviceable condition for now (2021).  Plan on replacement in 10 years.&lt;br /&gt;
|-&lt;br /&gt;
|Sump Pump&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$300&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Surge Tank&lt;br /&gt;
|1967&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$36,800&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|As of 2021, the [[Pool_Systems_Introduction#Surge_Tank|surge tank]] is overdue for an overhaul.  The tank in its present state is &amp;quot;severely deteriorated&amp;quot;, leaking, and lacking essential functionality presumably removed via low-budget modifications.  The cost for a full overhaul is estimated at $36,800 and must be performed when the pool is empty.&lt;br /&gt;
|-&lt;br /&gt;
|Variable Frequency Drive (VFD) for Main Pump Motor&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|10&lt;br /&gt;
|&lt;br /&gt;
|$1,200&lt;br /&gt;
|&lt;br /&gt;
|$1,500&lt;br /&gt;
|The main pump motor VFD is a Yaskawa GA50U2042ABA and was installed in 2022.  The lifespan is an estimate - and is subject to many variables.  Exposure to chemical vapors (chlorine, acid) and excess heat will reduce the lifespan.  Efforts have been made to limit exposure to both.  NOTE: The VFD has been shown to reduce club energy use by about 20 % (savings of $200-$300 a month in 2022).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Snack Shack ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Air Conditioner (Heat Pump)&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|12&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|The air conditioner (heat pump) is a single-zone, 18,000 BTU 230 V &amp;quot;mini-split&amp;quot; unit.  The indoor unit is LG p/n LSN180HEV2, and the outdoor unit is LG p/n LSU180HEV2.  Lifespan estimates place heat pumps at 10-15 years.  The replacement cost is not known.  NOTE: This unit was installed primarily to reduce the burden on the refrigeration units in the snack shack, which would often operate 24/7 during hot periods of the summer.&lt;br /&gt;
|-&lt;br /&gt;
|Drywall (Ceiling)&lt;br /&gt;
|2019&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The snack shack ceiling was replaced in 2019 due to failure (collapse).  There is no anticipated need to replace again at this time (at least not within the 20 year planning period).&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|15&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|The exhaust fan is a Broan L700.  Starting in 2022, its usefulness going forward will be greatly reduced due to the installation of the A/C unit.  &lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2019&lt;br /&gt;
|2021&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|$60&lt;br /&gt;
|$140&lt;br /&gt;
|$80&lt;br /&gt;
|$190&lt;br /&gt;
|Six-year maintenance ($38 in 2021 dollars) is due in 2025 and 2031.  Replacement ($90 in 2021 dollars) is due in 2031.  Annual servicing ($6 in 2021 dollars) is required.  Prices adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Ice Cream)&lt;br /&gt;
|2012&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|10&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$1,200&lt;br /&gt;
|&lt;br /&gt;
|The &amp;quot;Blue Bunny Ice Cream&amp;quot; freezer is a model 46SLC-LH-MFB, built in 2012.  The replacement cost is estimated to be $900 (an Avantco DFC16-HCL in 2021 dollars, adjusted for inflation in 2032).  Past experience during a power outage suggests that these units are not particularly well insulated.  A better replacement may be desired when the 20 year estimated lifespan (2032) arrives.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Upright)&lt;br /&gt;
|2014&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|12&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|$4,100&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a Supera F1R-1, DOM: 30-Mar-2014.  Last checked out by a refrigeration contractor in 2021.  The Supera brand is not well known/respected and may not last within the typical 15-20 year lifespan cited for commercial kitchen refrigeration units.  Repair parts may not be available (Supera appears to be defunct).  The estimated replacement cost is based upon an equivalent True unit.&lt;br /&gt;
|-&lt;br /&gt;
|Garbage Disposal&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|The installation date of the garbage disposal is not known at this time.&lt;br /&gt;
|-&lt;br /&gt;
|Microwave #1&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|$500&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a Sunbeam SGB8901.  This is a residential unit, and is over-stressed by high duty cycle use.  The average residential microwave is said to last 7 years - the estimate has been reduced to 5 as an estimate per the part-time heavy use.  The estimated replacement cost is based upon the purchase of a commercial microwave, better suited for the purpose.&lt;br /&gt;
|-&lt;br /&gt;
|Microwave #2&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|$500&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a Samsung MS11K3000AS.  This is a residential unit, and is over-stressed by high duty cycle use.  The average residential microwave is said to last 7 years - the estimate has been reduced to 5 as an estimate per the part-time heavy use.  The estimated replacement cost is based upon the purchase of a commercial microwave, better suited for the purpose.&lt;br /&gt;
|-&lt;br /&gt;
|Refrigerator&lt;br /&gt;
|1997&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$500&lt;br /&gt;
|$500&lt;br /&gt;
|$4,600&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a True T-23, DOM: 1-May-1997.  Last checked out by a refrigeration contractor in 2021.  Setting aside $500 in 1-5 years and $500 in 5-10 years for repairs, replacement with another a True unit in 10-15 (unit will be nearly 40 years old).  No known issues with the existing unit other than it is 24 years old (as of 2021), exceeding the expected lifespan.  That said - given the seasonal use, it may last longer.  A True unit is highly repairable (as long as the fundamentals such as the cabinet are sound).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Women&#039;s Restroom ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fans (Small)&lt;br /&gt;
|Unknown&lt;br /&gt;
|N/A&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are two small exhaust fans in the women&#039;s restroom.  The larger of the two (13&amp;quot; assumed) is missing, the smaller (9&amp;quot; assumed) is in place, but non-functional (motor seized).  Replacement is recommended as soon as the budget permits (cost to be determined).&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan (Large)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The exhaust fan in the women&#039;s restroom is in poor condition.  Replacement is recommended as soon as the budget permits (cost to be determined).&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Asset_Registry&amp;diff=1766</id>
		<title>Asset Registry</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Asset_Registry&amp;diff=1766"/>
		<updated>2025-01-04T12:54:52Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Asset Registry is maintained by Building &amp;amp; Grounds and reviewed by the board.  The original version was created by Sally Duffy and the 2020 Capital Assessment Committee.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Last Updated:&amp;lt;/b&amp;gt; January 4th, 2025&lt;br /&gt;
&lt;br /&gt;
Where possible, inflation is considered (using [https://smartasset.com/investing/inflation-calculator this calculator], for instance).  Future investment is a &amp;quot;best guess&amp;quot; based upon past quotes or work, where possible.  NOTE: A higher-than-expected inflation rate took effect in 2022.  This has not necessarily been factored into calculations (August 2022).  Many estimates were made in 2020 and 2021.&lt;br /&gt;
&lt;br /&gt;
Columns for &amp;lt;b&amp;gt;Failure Mode and Effect Analysis (FMEA)&amp;lt;/b&amp;gt; were added in January 2023.  The columns are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Severity (S):&amp;lt;/b&amp;gt; 1 = insignificant (minimal operational impact); 10 = catastrophic (the club cannot operate)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Occurrence (O):&amp;lt;/b&amp;gt; 1 = extremely unlikely; 10 = inevitable&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Detection (D):&amp;lt;/b&amp;gt; 1 = certain to detect; 10 = certain not to detect&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Risk Priority Number (RPN):&amp;lt;/b&amp;gt; The product of O, S and D.  0 = low risk; 1000 = highest risk&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FMEA Values are subjective.  The threshold of concern (for the RPN) is generally set to 200, though subject to revision.&lt;br /&gt;
&lt;br /&gt;
== Basement ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable mw-collapsible&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|FMEA&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2025)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
!S&lt;br /&gt;
!O&lt;br /&gt;
!D&lt;br /&gt;
!RPN&lt;br /&gt;
|-&lt;br /&gt;
|Breaker Panel ([[Electrical System#Basement Panel RLP-2|RLP-2]])&lt;br /&gt;
|1966&lt;br /&gt;
|2020&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|10&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|100&lt;br /&gt;
|The basement breaker panel is a Square D QO series (copper bus bar).  It is in good operating condition.  No plans to replace it for the foreseeable future.  The wiring was cleaned up and the branch side lugs were properly torqued in 2020.  New circuits added.  Very limited capacity left - additional circuits should be added to the upstairs panel (RLP-1).&lt;br /&gt;
|-&lt;br /&gt;
|Circulator Pump (Hot Water)&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|6&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$420&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|25&lt;br /&gt;
|The hot water circulator pump is a Grundfos Alpha2 15-55SFC (99163937) stainless steel circulation pump (1/16 HP).  The replacement cost is $330 in 2021 (maybe cheaper on surplus).  Circulation pumps are cited to last ten years - but as always, subject to environment and use.  As of 2021/2022, it was noted that the circulation function didn&#039;t really work correctly (2021/2022).  In 2024, an aquastat was added to (finally) address the issues.&lt;br /&gt;
|-&lt;br /&gt;
|Dehumidifier &amp;quot;A&amp;quot;&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|0&lt;br /&gt;
|$330&lt;br /&gt;
|$380&lt;br /&gt;
|$420&lt;br /&gt;
|$480&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|3&lt;br /&gt;
|192&lt;br /&gt;
|The existing model is a Toshiba TDDP5012ES2 50pint/day unit (DOM: 08/2019, but not placed into service until 2020).  The replacement cost is $300.  Dehumidifiers tend to be short-lived (especially in high humidity, high-duty cycle environments).  It is estimated that this unit may only last five years.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;B&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; While the severity of a failure is high (mold growth, if not resolved), this unit is easily replaceable and poses no risk to the operating status of the club.&lt;br /&gt;
|-&lt;br /&gt;
|Dehumidifier &amp;quot;B&amp;quot;&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|1&lt;br /&gt;
|$340&lt;br /&gt;
|$380&lt;br /&gt;
|$430&lt;br /&gt;
|$490&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|3&lt;br /&gt;
|192&lt;br /&gt;
|The existing model is a Frigidaire (Electrolux) FGAC7044U101 (DOM: 01/2019, but not placed into service until 2021).  The replacement cost is $300.  See the comments for &amp;lt;b&amp;gt;Dehumidifier &amp;quot;A&amp;quot;&amp;lt;/b&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|6&lt;br /&gt;
|$30&lt;br /&gt;
|$180&lt;br /&gt;
|$40&lt;br /&gt;
|$230&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The basement fire extinguisher is a Buckeye ABC unit (exact model TBD).  Six-year maintenance ($38 in 2021 dollars) is due in 2027 and 2037 (was originally due in 2023 per manufacture date but occurred in 2021).  Replacement ($90 in 2021 dollars) is due in 2029 and 2041.  Annual servicing ($6 in 2021 dollars) is required.  Prices are adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Foundation/Walls&lt;br /&gt;
|1966&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|18&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|$16,000&lt;br /&gt;
|7&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|175&lt;br /&gt;
|Installed a new internal weeping tile system and sump pump in 2021.  Assume that after 20 years, the system may need to be replaced (again) due to the eventual infiltration of sediment.  Painted basement walls with Liquid Rubber and Drylok in 2021.  Hydrostatic pressure is causing a bulge on the east wall (near the staircase).  TBD cost to address in the 5-10 year window (as of 2021) unless movement/cracking makes the project more urgent.  As of 2022, some breakdown is visible in the corners (discoloration, visible water).  This may be corrected on a spot basis.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Chest)&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|20&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|8&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|32&lt;br /&gt;
|The existing model is a Kelvinator Commercial KCCF170WH (59 1/2&amp;quot;, 17 cu ft capacity).  The date of manufacture is not known.  The replacement cost in 2021 is about $930.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Chest)&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|14&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$1,300&lt;br /&gt;
|8&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|32&lt;br /&gt;
|The existing model is an Electrolux KCCF160QWA commercial freezer (15.58 cu ft capacity).  This model does not appear to be made anymore; replacement with a KCCF170WH or equivalent (replacement cost in 2021 is about $930; about $1,300 in 2036 with inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Ice Cream)&lt;br /&gt;
|2010&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|Failed&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&amp;lt;b&amp;gt;2023 Update:&amp;lt;/b&amp;gt; This unit has been identified to have failed in the prior year and is subject to replacement.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Blue Bunny Ice Cream&amp;quot; freezer is a model RIO S125, built in 2010.  The replacement cost is estimated at $900 (an Avantco DFC16-HCL in 2021 dollars, adjusted for inflation in 2030).  Experience during a power outage suggests that these units are poorly insulated.  A better replacement may be desired when the 20-year estimated lifespan (2030) arrives.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Upright)&lt;br /&gt;
|2013&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|11&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|8&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|32&lt;br /&gt;
|The existing model is a Whirlpool EV161NZTQ02 household freezer.  The replacement cost is not known at this time.&lt;br /&gt;
|-&lt;br /&gt;
|Main Distribution Panel&lt;br /&gt;
|1966&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|10&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|100&lt;br /&gt;
|The distribution panel was informally inspected in 2021.  No signs of issues.  No plans for service or replacement soon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;B&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; Regular inspections are required.&lt;br /&gt;
|-&lt;br /&gt;
|Network Equipment&lt;br /&gt;
|2020&lt;br /&gt;
|2022&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|5&lt;br /&gt;
|3&lt;br /&gt;
|2&lt;br /&gt;
|30&lt;br /&gt;
|Some equipment replacement is anticipated every five years due to product end-of-life (EOL), failures, or technology upgrades.  The cost is not known at this time.  A new PoE network switch was installed in the clubhouse in 2022.  NOTE: For the sake of security, specifics about the network are not posted on the Wiki.&lt;br /&gt;
|-&lt;br /&gt;
|Sump Pump&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$300&lt;br /&gt;
|&lt;br /&gt;
|7&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|175&lt;br /&gt;
|The sump pump is a Foundation Systems of Michigan (FSM) Elite 365 AquaStop Sump Pump System (1/3 HP).  Replacement after ten years is anticipated.&lt;br /&gt;
|-&lt;br /&gt;
|Tempering Valve&lt;br /&gt;
|2020&lt;br /&gt;
|2021&lt;br /&gt;
|8&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|6&lt;br /&gt;
|&lt;br /&gt;
|$5,300&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|50&lt;br /&gt;
|The tempering valve is a Powers LFMM 433-13 (1-1/4&amp;quot; 110 GPM).  This part number (as written in the plumbing invoice) needs to be confirmed; the -13 suffix doesn&#039;t seem to align with an actual part number.  Tempering valves are cited to last 5-8 years in general.  The impact of seasonal use is TBD.  As of 2021, the functionality of the tempering valve and its interaction with the hot water circulation pump has been problematic.  An additional effort may be required in 2022.  The temperature/pressure gauge failed in 2021 and was replaced with a Watts WLFDPTG330200D.  The material and labor cost in 2020 was about $5,300; replacement in 2028 adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|UPS Batteries (Network)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$60&lt;br /&gt;
|$70&lt;br /&gt;
|$80&lt;br /&gt;
|$90&lt;br /&gt;
|3&lt;br /&gt;
|6&lt;br /&gt;
|3&lt;br /&gt;
|54&lt;br /&gt;
|The network battery backup is an APC Smart-UPS SMC1500-2U.  It uses four [https://www.power-sonic.com/product/ps-1270/ PS-1270] lead-acid batteries (the replacement cost for the Power-Sonic brand is $13 each from a local distributor).&lt;br /&gt;
|-&lt;br /&gt;
|Water Heater&lt;br /&gt;
|2007&lt;br /&gt;
|2018&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$20,000&lt;br /&gt;
|&lt;br /&gt;
|$27,000&lt;br /&gt;
|&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|512&lt;br /&gt;
|The [domestic hot] water heater is confirmed to have been installed in 2007, both by the serial number and the permit pulled noted in [[Club History#2007|club history]].  The existing unit is a Lochinvar TNR200-100 (100-gallon) fully condensing water heater.  The standard &amp;quot;rule of thumb&amp;quot; is to pre-emptively replace a water heater at the 10-year mark.  However, the fact that the water heater is drained and dormant from about September to April should have some longevity benefits.  Replacement is assumed to be necessary within the 5-10 year span (as of 2021), if not earlier.  The replacement cost is based on a quote received for labor and materials in early 2023.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; It is assumed that the domestic hot water heater is critical to club operation (for health code reasons), and the club cannot operate without it.  Detecting a failure is difficult (water heaters often fail with little to no warning once they cross the decade-old mark).  Failure is more or less &amp;quot;inevitable&amp;quot; for a residential-grade unit.  It&#039;s not clear how the commercial-grade unit differs.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basketball and Tennis Courts ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|FMEA&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2023)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
!S&lt;br /&gt;
!O&lt;br /&gt;
!D&lt;br /&gt;
!RPN&lt;br /&gt;
|-&lt;br /&gt;
|Basketball Poles&lt;br /&gt;
|2018&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|20&lt;br /&gt;
|Lifespan, replacement plans, and replacement cost are TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Surface (Basketball)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|$38,000&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are essentially four options given the court conditions:&lt;br /&gt;
# Powerwash to clean.  Fill cracks with acrylic crack filler, then resurface and paint for about $20,000.  Based on just short of 900 ft of cracks at 2020 pricing.  This is a very short-term solution; assume cracks will re-appear after a large day/night temperature swing (and especially after a freeze/thaw).  For that reason, this repair is not recommended.&lt;br /&gt;
# The same as the prior option, plus fabric overlay crack repair (2-year guarantee) for about $33,000.  This solution should last 4-5 years (after which cracks may re-appear).  This may be the best solution for the near term.  For this option, the sport coating contractor may be hired directly.&lt;br /&gt;
# Grind down 2 inches of the surface, then re-build for about $100,000 ($50,000 per court).  For this option, hire a paving contractor; the sport coating is subcontracted.&lt;br /&gt;
# Demolish, add improved drainage, then rebuild for about $150,000 ($75,000 per court).  This is by far the most expensive, but the most effective solution depending upon the underlying issues (i.e. very wet grounds).  For this option, hire a paving contractor; the sport coating is subcontracted.&lt;br /&gt;
Given current budgets, it seems likely that option #2 is the best choice for the 5-10 year window.  The lifespan of 5 years assumes repeated use of option #2.&lt;br /&gt;
|-&lt;br /&gt;
|Surface (Tennis)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|$42,000&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are essentially four options given the court conditions:&lt;br /&gt;
# Powerwash to clean.  Fill cracks with acrylic crack filler, then resurface and paint per USTA standards for about $23,000.  Based on just short of 1000 ft of cracks at 2020 pricing.  This is a very short-term solution; assume cracks will re-appear after a large day/night temperature swing (and especially after a freeze/thaw).  For that reason, this repair is not recommended.&lt;br /&gt;
# The same as the prior option, plus fabric overlay crack repair (2-year guarantee) for about $37,000.  This solution should last 4-5 years (after which cracks may re-appear).  This may be the best solution for the near term.  For this option, the sport coating contractor may be hired directly.&lt;br /&gt;
# Grind down 2 inches of the surface, then re-build for about $100,000 ($50,000 per court).  For this option, hire a paving contractor; the sport coating is sub-contracted.&lt;br /&gt;
# Demolish entirely, add improved drainage, then re-build for about $150,000 ($75,000 per court).  This is by far the most expensive, but the most effective solution depending upon the underlying issues (i.e. very wet grounds).  For this option, hire a paving contractor; the sport coating is sub-contracted.&lt;br /&gt;
Given present budgets, it seems likely that option #2 is the best choice for the 5-10 year window.  The lifespan of 5 years assumes repeated use of option #2.&lt;br /&gt;
|-&lt;br /&gt;
|Tennis Nets&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|New Edwards 30LS &amp;quot;Wimbledon Nets&amp;quot; were purchased in late 2021 and installed in the spring of 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Tennis Pole Hardware&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|$150&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The age of the existing poles is not known.  In 2022, two new &amp;quot;53420-B EZ Tennis Post Replacement Reels&amp;quot; from &amp;quot;Tennis Court Supply&amp;quot; were installed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Clubhouse ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2023)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|Awning&lt;br /&gt;
|1997&lt;br /&gt;
|2020&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|It appears (but has not been confirmed) that the awning was installed in 1997.  The fabric material is assumed to be Sunbrella, with a 10-year rated lifespan.  However, 24 years later (as of 2021), it still looks good.  The fabric was cleaned per manufacturer recommendations in 2020.  No planned replacement until it is aesthetically necessary.&lt;br /&gt;
|-&lt;br /&gt;
|Breaker Panel ([[Electrical System#Basement Panel RLP-1|RLP-1]])&lt;br /&gt;
|2007&lt;br /&gt;
|2022&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The &amp;quot;upstairs&amp;quot; panel was added in [[Club History#2007|2007]] presumably to support additional circuits (hand dryers, etc).  There are no plans to replace it in the 20-year window.  The panel was last serviced in 2022.  Lug torques were verified, and new circuits were added.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; Regular inspections are required to meet the &amp;quot;detection&amp;quot; value.&lt;br /&gt;
|-&lt;br /&gt;
|Changing Table&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|17&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The baby changing station is a Koala Kare KB200 (replacement cost is $210 based on average online pricing as of 2021).  The lifespan is a guess and may be adjusted depending on observations of wear and tear in future years.  There is no planned replacement within the 20-year window (as of 2023).&lt;br /&gt;
|-&lt;br /&gt;
|Chimney&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The chimney is most likely original to the 1966 structure.  It is functionally obsolete; the only device producing combustion gases in the clubhouse is vented via PVC pipe.  Unfortunately, the mortar appears to be failing.  Tuckpointing is recommended shortly.  Alternatively, the chimney could potentially be removed.&lt;br /&gt;
|-&lt;br /&gt;
|Computer&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|3&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|A regular refresh cycle for the front-desk computer is planned.  The replacement cost is TBD (donated/retired business PCs preferred).&lt;br /&gt;
|-&lt;br /&gt;
|Drywall (Family Restroom Ceiling)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The family restroom ceiling was replaced in 2020 upon discovery that it was sagging several inches in the middle of the room.  No replacement is planned.&lt;br /&gt;
|-&lt;br /&gt;
|Drywall (Lobby Ceiling)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Repairs were made to the drywall near the north end (to address sagging) during the 2022 lobby renovation.  At this time, it was observed that repairs had previously been made near the &amp;quot;Fairway Farms&amp;quot; glass by the stairs.  No replacement is planned.&lt;br /&gt;
|-&lt;br /&gt;
|Electrical&lt;br /&gt;
|1966&lt;br /&gt;
|2020&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|7&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&amp;lt;p&amp;gt;Much of the wiring in the clubhouse is original to the 1966 installation.  Fortunately, #12 AWG copper was run in rigid conduit throughout.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;In 2020, the wiring was inspected and found in good condition.  Nearly all receptacles, switches, and fixtures were replaced.  All associated connections (screws, wire nuts) were removed, cleaned of oxidation, and re-terminated.  Wiring in panels ([[Electrical System#Basement Panel RLP-1|RLP-1]] and [[Electrical System#Basement Panel RLP-2|RLP-2]]) was cleaned up, and all branch-side lugs were torqued to spec.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;The basement switchgear was inspected and deemed to be in good operating condition (no replacement planned).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Replacement of certain receptacles, switches, and fixtures may be needed on a 10-year interval.  The cost is TBD.&amp;lt;/p&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Exit Signs&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$80&lt;br /&gt;
|$90&lt;br /&gt;
|$100&lt;br /&gt;
|$120&lt;br /&gt;
|The lifespan of the two exit signs is largely determined by the ability of the internal rechargeable batteries to sustain 90 minutes of illumination upon power failure.  This is an annual city inspection requirement (Livonia Code of Ordinances 15.32.030).  The battery pack may be replaceable.  If not, off-brand exit signs with floodlights can be had for as little as $40 (or less) on Amazon.&lt;br /&gt;
|-&lt;br /&gt;
|Fans (Pedestal)&lt;br /&gt;
|1995&lt;br /&gt;
|None&lt;br /&gt;
|50&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|22&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are two pedestal fans in the clubhouse.  One appears to be from 1995; the date of manufacture for the other is unknown (TBD).  The fans are anticipated to last beyond the 20-year view (as of 2021). Minor repairs may be needed; the cost is TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2016&lt;br /&gt;
|2020&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|$70&lt;br /&gt;
|$140&lt;br /&gt;
|$80&lt;br /&gt;
|$180&lt;br /&gt;
|The clubhouse (lobby) fire extinguisher is an Advantage ADV-10, as of 2021, last serviced in May 2020 (per punch tag).  Six-year maintenance ($38 in 2021 dollars) is assumed to be due in 2022 and 2034. Replacement ($90 in 2021 dollars) is due in 2028 and 2040. Annual servicing ($6 in 2021 dollars) is required. Prices are adjusted for inflation. &lt;br /&gt;
|-&lt;br /&gt;
|Floor&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Any rehabilitation or replacement of the floor in the clubhouse (main floor) is yet to be discussed.  The original installation date is not known.&lt;br /&gt;
|-&lt;br /&gt;
|Gutters&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Gutters are in disrepair (leaking) and should be replaced.  The plan is for the 5-10 year window (as of 2021).  We received quotes in 2020 that need to be located for reference.&lt;br /&gt;
|-&lt;br /&gt;
|Hand Dryers&lt;br /&gt;
|2007&lt;br /&gt;
|None&lt;br /&gt;
|25&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|The existing American Dryer (Global Dryer) model GX1 units were installed in [[Club_History#2007|2007]].  Lifespan is a guess.  The estimated cost is for two replacement units in 2032 ($150/ea in 2021 prices).  Labor is not included.&lt;br /&gt;
|-&lt;br /&gt;
|Lights (Vapor-Proof)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|16&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|The fixtures are TOGGLED FV420PO-A423-40230 (includes 2 x 4000K 23 W 3,100 lumen bulbs).  The replacement cost in 2021 is about $65 per fixture.  TOGGLED rates the bulbs for 16 years (subject to vary based on exposure and usage).  No replacement cost is given for 2036, as technology may dictate a different solution.&lt;br /&gt;
|-&lt;br /&gt;
|PA Amplifier&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|17&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$1,300&lt;br /&gt;
|The amplifier&#039;s lifespan is based upon many factors; 20 years is an educated guess.  The biggest enemies to its longevity are excessive heat, dirt infiltration, and condensation.  Keeping the amplifier cool and clean is critical.  Often amplifiers fail due to their power supply capacitors failing; these may or may not be replaceable (the unit may be serviceable).  The cost is an estimate based on the retail cost of the existing JBL CSMA 2120, plus inflation, in 2040.&lt;br /&gt;
|-&lt;br /&gt;
|Radios&lt;br /&gt;
|2013&lt;br /&gt;
|2021&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$80&lt;br /&gt;
|$95&lt;br /&gt;
|$110&lt;br /&gt;
|$120&lt;br /&gt;
|There are six Motorola MH230R FRS/GMRS radios in the clubhouse, used for grounds-wide communication.  Four radios were purchased in 2021 to match the existing two units on hand.  New &amp;quot;old stock&amp;quot; KEBT-086-C batteries were installed in 2021.  Three charging stations are used to trickle-charge the NiMH battery packs.  Based on observations in 2021, these radios are used and abused quite hard; regular replacement is assumed.  Assume a replacement cost of $80 for two radios per 5-year interval, adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;div id=&amp;quot;0001&amp;quot;&amp;gt;Roof&amp;lt;/div&amp;gt;&lt;br /&gt;
|2014&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|11&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The assumption is that the clubhouse roof was replaced in [[Club History#2014|2014]].&lt;br /&gt;
|-&lt;br /&gt;
|Steel Doors&lt;br /&gt;
|1966&lt;br /&gt;
|Unknown&lt;br /&gt;
|30&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$8,200&lt;br /&gt;
|&lt;br /&gt;
|$8,000&lt;br /&gt;
|&lt;br /&gt;
|The steel doors appear to be original to the building.  There are nine doors in total: two for the lobby exterior, two for the family restroom, three for the men&#039;s room, and two for the women&#039;s room.  It has been proposed to replace the two exterior restroom doors and the interior men&#039;s room door as soon as possible.  Then, replace the two doors between the men&#039;s and women&#039;s room and lobby in five years or less.  The other exterior and interior doors may need to be replaced in 10-15 years.  Costs are based on estimates received in 2023.&lt;br /&gt;
|-&lt;br /&gt;
|Showers&lt;br /&gt;
|TBD&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Soffit&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The wooden soffit is in disrepair and needs replacement with a low-maintenance product.  The venting grate is failing and has allowed animal intrusion.  The replacement should coincide with gutter (and possible fascia) replacement.  No estimates have been made at this point.&lt;br /&gt;
|-&lt;br /&gt;
|Toilets&lt;br /&gt;
|TBD&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The installation date of the toilets is not known.  NOTE: Toilet valves are a separate topic.&lt;br /&gt;
|-&lt;br /&gt;
|Toilet Valves&lt;br /&gt;
|1966&lt;br /&gt;
|2021&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|3&lt;br /&gt;
|$1,100&lt;br /&gt;
|$1,300&lt;br /&gt;
|$1,400&lt;br /&gt;
|$1,600&lt;br /&gt;
|Numerous toilet valves were replaced in 2021.  Some additional refurbishment in 2022 (this is an annual need).  Rebuild kits may work; replacement is suggested after numerous rebuilds.&lt;br /&gt;
|-&lt;br /&gt;
|UPS Batteries (Front Desk)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$30&lt;br /&gt;
|$30&lt;br /&gt;
|$40&lt;br /&gt;
|$40&lt;br /&gt;
|The front desk battery backup is an APC Back-UPS XS 1500.  It uses two [https://www.power-sonic.com/product/ps-1270/ PS-1270] lead-acid batteries (the replacement cost for the Power Sonic brand is $13 each from a local distributor).&lt;br /&gt;
|-&lt;br /&gt;
|Windows (Exterior)&lt;br /&gt;
|1967&lt;br /&gt;
|None&lt;br /&gt;
|N/A&lt;br /&gt;
|N/A&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The exterior windows appear to be original to the facility (except for the newer exterior window in the Snack Shack).  No plans to replace.&lt;br /&gt;
|-&lt;br /&gt;
|Window Shutters&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Grounds ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2023)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|Fence (Property Line)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Patio Sets&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Discussion of replacement of the patio sets is pending.&lt;br /&gt;
|-&lt;br /&gt;
|Parking Lot&lt;br /&gt;
|2000&lt;br /&gt;
|2020&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$14,400&lt;br /&gt;
|$16,300&lt;br /&gt;
|$18,500&lt;br /&gt;
|$20,800&lt;br /&gt;
|The asphalt parking lot was first installed in 2000.  Maintenance is necessary every 5-7 years (largely subject to weather).  Maintenance was known to have been performed in [[Club History#2015|2015]] and 2020.  Costs for 2025, 2030, 2035, and 2040 are based on the prior estimate (for 2020) with inflation.  NOTE: There has been some discussion (Spring 2023) whether a complete re-surfacing may be required?  Cost might be as high as $100k?  To be discussed further.&lt;br /&gt;
|-&lt;br /&gt;
|Picnic Tables (Plastic)&lt;br /&gt;
|2007&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|A spot check of a few tables suggests that the entire lot may have been purchased (or at least manufactured) in 2007.  Some tables are starting to fail mechanically and have been temporarily repaired.  Some of the painted metal parts are flaking/rusting.  It likely makes the most sense to start purchasing a small number of tables to begin the replacement of the worst units over time - unless there is a substantial benefit from a bulk order.  The lifespan of 20 years is based on current wear and tear.  It seems possible that within 5 years (from 2022), the condition of some tables may be approaching &amp;quot;poor&amp;quot;.  To be determined.&lt;br /&gt;
|-&lt;br /&gt;
|Picnic Tables (Wooden)&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|2021&lt;br /&gt;
|Unknown&lt;br /&gt;
|$100&lt;br /&gt;
|$110&lt;br /&gt;
|$130&lt;br /&gt;
|$150&lt;br /&gt;
|Outright replacement of the wooden picnic tables (7 on the property as of 2021) is not anticipated.  Instead, periodic wood/hardware replacement and stripping/painting should keep the tables in good working order.  Predicting maintenance costs is difficult, given the volatile cost of lumber.  Assume $100 every 5 years, adjusted for inflation.  All tables were power-washed and painted in 2021.&lt;br /&gt;
|-&lt;br /&gt;
|Play Structure&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|The present Miracle Recreation play structure (and swing sets) were installed in 2016.  Miracle recommends playground updates every 8-10 years; playgrounds can last 10-20 or more years, dependent upon weather and usage.  An estimated replacement date of 20 years is given, though the equipment may last longer.  Regular inspections must be performed.  Assume some maintenance cost within 5-10 years (from 2021).&lt;br /&gt;
|-&lt;br /&gt;
|Privacy Fence&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Installed in 2020, minor repairs in 2021.&lt;br /&gt;
|-&lt;br /&gt;
|Shed&lt;br /&gt;
|1986&lt;br /&gt;
|2021&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The shed was installed in 1986.  A new roof, siding (west side), and doors were installed in 2021.&lt;br /&gt;
|-&lt;br /&gt;
|Speakers&lt;br /&gt;
|2020&lt;br /&gt;
|-&lt;br /&gt;
|Water Gate Valve&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|40&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|37&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The prior gate valve lasted about 40 years before showing issues; it is assumed that the [[Water Gate Valve#History|new gate valve]] will have a similar lifespan.  No planned maintenance or replacement prior to 2061.&lt;br /&gt;
|-&lt;br /&gt;
|WiFi APs&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$380&lt;br /&gt;
|$420&lt;br /&gt;
|$480&lt;br /&gt;
|$540&lt;br /&gt;
|The present APs were installed in 2020 and are fully supported as of 2021.  An estimated life of 5 years is given, largely due to the likelihood that the product will go EOL by then.  2 of the 3 APs are mounted outdoors, and the 3rd exists in a non-climate-controlled building (clubhouse).  The APs are powered year-round to help drive off potential internal condensation.  Still, exposure may reduce their lifespan.  If the product is still supported after the 5-year mark (2025), and the units are functional, an evaluation of the performance vs. a replacement should be considered.  The replacement cost in 2021 is $125/ea (3 units).  A replacement cycle of 5 years is assumed (units may remain in service longer).&lt;br /&gt;
|-&lt;br /&gt;
|Volleyball Net&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|3&lt;br /&gt;
|&lt;br /&gt;
|$220&lt;br /&gt;
|$250&lt;br /&gt;
|$280&lt;br /&gt;
|The decision to purchase a more durable volleyball net in 2021 appears to have been a good one; the net held up well for the whole season (versus cheaper nets that had to be replaced sometimes multiple times per season).  A lifespan of 5 years is anticipated, as UV will eventually break down the vinyl.  The existing net is a [https://www.volleyballusa.com/hd2-heavy-duty-volleyball-net/ VolleyballUSA HD2].  The replacement cost is $200, adjusted for inflation on a 5-year interval.  &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Large Pavilion ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Ceiling Fans&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$640&lt;br /&gt;
|&lt;br /&gt;
|The ceiling fans (2) are Home Decorators Collection Windward 68-in units (Home Depot SKU #1004794977).  The replacement cost as of 2021 is $249/ea (adjusted to $320/ea for 2030).  An estimated lifespan of 10 years is predicted (assuming proper off-season storage per B&amp;amp;G standard procedure).  An equivalent replacement should be as large as possible (i.e. 68-in diameter) and with integrated LED lighting.&lt;br /&gt;
|-&lt;br /&gt;
|Roof&lt;br /&gt;
|2008&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The roof is assumed to be original to pavilion construction in [[Club History#2008|2008]].  It was noted by a contractor performing repairs in 2021 that the shingles&#039; spacing is incorrect.  The repair was made to match the improper spacing.&lt;br /&gt;
|-&lt;br /&gt;
|Gas Grills&lt;br /&gt;
|2012&lt;br /&gt;
|2020&lt;br /&gt;
|30&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|21&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|Lifespan is a guess.  Installed in 2012.  Grills were largely rebuilt/refurbished in 2020.  Replacement parts should keep them going for the foreseeable future.  Maintenance costs are TBD.  NOTE: Additional maintenance is planned during the off-season between 2022 and 2023.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Men&#039;s Restroom ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fans (Small)&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan (Large)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Projector&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The existing projector is a Viewsonic PJD555W (DLP 1280x800 WXGA, 20,000:1 contrast, 3,300 lumens).  It is discontinued by the manufacturer (as of 2017).  Lamp hours as of 2021 not know (lifespan is 5,000 hours).  Replacement may be desired to purchase a higher-lumen model to allow utilization before dusk (low priority).  A lifespan of 10 years has been assigned; it&#039;s assumed that by 2027, a replacement will be desired.  Movie nights in 2022 were hosted using member-provided equipment.&lt;br /&gt;
|-&lt;br /&gt;
|Projector Screen&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|This item is TBD.  Two &amp;quot;old&amp;quot; projector screens were removed and discarded in 2022.  A third (new-in-box) remains in the basement.  Movie nights in 2022 were hosted using member-provided equipment.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Pool ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Anchors (Backstroke Flags)&lt;br /&gt;
|Unknown&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|Unknown&lt;br /&gt;
|$250&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are four backstroke flag anchors in the pool deck.  The two anchors at the east end of the pool have failed and need to be replaced.  An estimated cost of $250 (2021 pricing) covers the cost of materials and tool rental (no labor cost).  NOTE: All four anchors may be replaced due to possible improper placement with respect to the ends of the pool.&lt;br /&gt;
|-&lt;br /&gt;
|Anchors (Starting Block)&lt;br /&gt;
|2018&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|18&lt;br /&gt;
|-&lt;br /&gt;
|Cover&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Need to determine the expected lifetime.  No replacement is planned in the 1-5 year term.&lt;br /&gt;
|-&lt;br /&gt;
|Diving Board&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|$6,500&lt;br /&gt;
|&lt;br /&gt;
|$8,300&lt;br /&gt;
|The diving board installed in 2020 is a Duraflex 16&#039; Modified Maxiflex Model &amp;quot;B&amp;quot;.  The replacement cost is estimated at $5,000 as of 2020.  Replacement is recommended every 7-10 years, but may vary due to outdoor/seasonal use.  Regular inspection is required to identify cracks or stress marks.&lt;br /&gt;
|-&lt;br /&gt;
|Drain Grates&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Drain grates have an expiration date.  Likely to be replaced during the pool renovation (2022).&lt;br /&gt;
|-&lt;br /&gt;
|Guard Stand (West)&lt;br /&gt;
|TBD&lt;br /&gt;
|2022&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The west guard stand appears to be a [https://www.spectrumproducts.com/stimson-lifeguard-chair-5-57308/ Spectrum Aquatics Stimson Lifeguard Chair (57308)].  A rough estimate for replacement cost is about $6,400.  The rotating base for the chair was replaced in 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Guard Stand (North)&lt;br /&gt;
|1990&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|It appears that the north guard stand, made by SR Smith, was installed in 1990.  No further information is available at this time.  No planned replacement or maintenance at this time (TBD).&lt;br /&gt;
|-&lt;br /&gt;
|Guard Umbrellas&lt;br /&gt;
|-&lt;br /&gt;
|Handrails&lt;br /&gt;
|-&lt;br /&gt;
|Ladders&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|$400&lt;br /&gt;
|$450&lt;br /&gt;
|$510&lt;br /&gt;
|$570&lt;br /&gt;
|There are 5 4-step ladders in the pool.  The original date of purchase is not known.  Most of the ladders appear to be of SR Smith make, though at least one ladder is an &amp;quot;Aquatech&amp;quot;.  Replacement of whole ladders is not anticipated.  Repairs (i.e., replacement steps/bolts) may be needed periodically.  As of 2020, an SR Smith ladder step with bolts costs about $50.  Anticipate replacement of two steps and two anchors (estimated at $250 in 2020) every five years.&lt;br /&gt;
|-&lt;br /&gt;
|Lane Markers&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|A Competitor brand 4&amp;quot; 25-meter racing lane (marker) cost is about $430 as of 2021.  There are 6 lanes in the pool (requiring 5 markers).  The age and condition of the existing markers is TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Marcite&lt;br /&gt;
|1966&lt;br /&gt;
|Unknown&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$100,000&lt;br /&gt;
|&lt;br /&gt;
|$128,000&lt;br /&gt;
|&lt;br /&gt;
|Pricing subject to further review; a budgetary estimate.  The plan for 2022 replacement is being developed [[Pool Marcite#Plan for 2022|here]].  Assume some amount of marcite replacement is necessary every 10 years.&lt;br /&gt;
|-&lt;br /&gt;
|Safety Ropes&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Two safety ropes (rope floats) are present in the pool:&lt;br /&gt;
* Between the &amp;quot;kiddie pool&amp;quot; and main pool (11 ft)&lt;br /&gt;
* Between the main pool and the diving well (27 ft)&lt;br /&gt;
Ropes were replaced with all-new parts for the 2022 season.&lt;br /&gt;
|-&lt;br /&gt;
|Slides&lt;br /&gt;
|2007&lt;br /&gt;
|2020&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|$10,200&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The south slide is an [https://www.srsmith.com/en-us/products/pool-slides/turbotwister/ SR Smith TurboTwister], the north slide is an [https://www.srsmith.com/en-us/products/pool-slides/typhoon/ SR Smith Typhoon].  The replacement cost is $4,000 and $2,900 based on average 2021 online pricing.  The installation date of the existing slides is unknown; a serial number suggesting 2008 appears on the Typhoon.  Both slides show signs of deterioration (superficial cracking as of 2021) and are targeted for replacement within 5-10 years.  Epoxy patching will be used in the meantime.  The replacement cost is estimated for 2028 and includes $2,000 for labor.  The listed lifespan is an estimate and based upon this target date.&lt;br /&gt;
|-&lt;br /&gt;
|Underwater Lights&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|Varies&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$6,600&lt;br /&gt;
|$1,000&lt;br /&gt;
|$1,000&lt;br /&gt;
|$7,000&lt;br /&gt;
|The proposal to retrofit pool lights is detailed [[Lighting#2022 Retrofit Proposal|here]].  $1,000 has been added to that cost to install new Aladdin rings during 2022.  $2,000 covers potential repairs/replacements through 2036, $7,000 has been estimated to replace the LEDs (best guess lifespan is about 15 years).&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Pool Deck ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Chairs&lt;br /&gt;
|Varies&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|Some regular chairs are in need of repair/replacement.  As of the manager&#039;s last accounting in 2021, of the 29 regular chairs, 9 are in need of repair.  Numbers to be confirmed.  A plan should be formed to begin staged replacement.  Coordination with other area clubs may be cost beneficial.&lt;br /&gt;
|-&lt;br /&gt;
|Concrete&lt;br /&gt;
|1967&lt;br /&gt;
|2018&lt;br /&gt;
|30&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|Portions of the concrete pool deck presumably date back to the original installation in [[Club History#1967|1967]].  Multiple repairs and deck replacements have been made since then.  As of 2021, the most recent work appears to have occurred in [[Club History#1998|1998]], [[Club History#2017|2017]] and [[Club History#2018|2018]].  Regular future maintenance is anticipated; the cost is TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Fence&lt;br /&gt;
|2014&lt;br /&gt;
|-&lt;br /&gt;
|Funbrella&lt;br /&gt;
|TBD&lt;br /&gt;
|2022&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|A new crank mechanism from Anchor Industries (maker of the Funbrella) was purchased and installed in August 2022.  The prior crank mechanism had &amp;quot;worn out&amp;quot; its friction plate.  Further maintenance (hardware replacement) is planned for the structural portions.  The original installation date of the Funbrella is not known.&lt;br /&gt;
|-&lt;br /&gt;
|Lounges&lt;br /&gt;
|Varies&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|A significant number of the lounge chairs are in need of repair/replacement.  As of the manager&#039;s last accounting in 2021, of the 187 lounge chairs, 6 are not usable.  A significant number of the others are worn and should be replaced in the near future.  Numbers to be confirmed.  A plan should be formed to begin staged replacement.  Coordination with other area clubs may be cost beneficial.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Pump House ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Acid Pump&lt;br /&gt;
|2017&lt;br /&gt;
|Unknown&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The acid pump is a Stenner 45M5.  The replacement cost in 2021 is about $400.&lt;br /&gt;
|-&lt;br /&gt;
|Boiler&lt;br /&gt;
|2004&lt;br /&gt;
|2022&lt;br /&gt;
|10&lt;br /&gt;
|TBD&lt;br /&gt;
|$2,500&lt;br /&gt;
|$25,000&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|It is difficult to say how long the pool heater should last.  The plan (as of 2021) is to replace in 5-10 years.  Multiple inspections and component replacements were made in 2020, 2021 and 2022.  The heat exchanger was replaced around 2011 (the exact year is not known).  It is expected that some burners may need to be replaced around 2025-2026 ($2,500 or less).  Some references indicate that the pool heater may only last 10 years, but this is subject to several variables.&lt;br /&gt;
|-&lt;br /&gt;
|Breaker Panel ([[Electrical System#Basement Panel RLP-3|RLP-3]])&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The date of installation of the breaker panel in the pump house is not known.  No immediate plans are in place to replace it.  It should be noted that it utilizes an aluminum bus bar, which is inherently incompatible with the corrosive environment in which it exists.&lt;br /&gt;
|-&lt;br /&gt;
|Chlorinator Pump&lt;br /&gt;
|2013&lt;br /&gt;
|2022&lt;br /&gt;
|15&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|$300&lt;br /&gt;
|&lt;br /&gt;
|$540&lt;br /&gt;
|&lt;br /&gt;
|The chlorinator pump appears to be original to the chlorinator install (about 2013).  The shaft seal was replaced in 2021 and again in 2022.  The faceplate seal was replaced in 2022.  Prior to that, the shaft seal (and faceplate) were replaced in 2018.  The lifespan estimate has been bumped up to 13 years, though continued periodic maintenance of seals is expected.  It is a bit difficult to judge how long it may last, as it operates at a relatively low duty cycle but is exposed to super-chlorinated water and vapors.  The existing motor is a Hayward Century SP1515-Z-1-EFTC 1.5 HP pool pump.  The estimated replacement cost is $300.  Shaft seal replacement (parts and labor) costs about $100; the seals alone are significantly cheaper.&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|&lt;br /&gt;
|$180&lt;br /&gt;
|$200&lt;br /&gt;
|$220&lt;br /&gt;
|The exhaust fan is a Dayton 10N201 (1/6 HP 1400 CFM).  The thermostat circuit has been bypassed; the fan is intended to operate 24/7 when the pool is operating.  The estimated useful life is based upon an assumption that the chemical vapors may cause premature failure.  The fan may last significantly longer.&lt;br /&gt;
|-&lt;br /&gt;
|Filter Sand&lt;br /&gt;
|2013&lt;br /&gt;
|2021&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|1&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|The pool filter tank sand was last changed in [[Club History#2013|2013]].  For an outdoor pool, this generally should be done every 10 years (which can coincide with marcite replacement).  The cost is pending.  The sand was stirred in 2021 and 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|$110&lt;br /&gt;
|$330&lt;br /&gt;
|$150&lt;br /&gt;
|The pump house fire extinguisher an Amerex model 240, filled with water and anti-freeze to suppress chemical fires.  Five-year maintenance ($100 in 2021) is due in 2026 and 2036 (installed in 2021).  Replacement ($260 in 2021) is due in 2031 (10 years).  Prices are adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Flow Meter (Bypass)&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Flow Meter (Output)&lt;br /&gt;
|-&lt;br /&gt;
|Garage Door&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|30&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|28&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|A new Ideal Door brand 8 ft x 7 ft white insulated (R-Value 6.5) garage door was installed in 2020.  Replacement is not anticipated until around 2050.  The replacement cost (in 2021 dollars) is about $400, excluding the cost of additional materials (hardware, trim, etc).  &lt;br /&gt;
|-&lt;br /&gt;
|GFCI Switches &lt;br /&gt;
|None&lt;br /&gt;
|2020&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|$220&lt;br /&gt;
|&lt;br /&gt;
|$290&lt;br /&gt;
|The GFCI switches in the pump house (also referred to as &amp;quot;dead front GFCI outlets&amp;quot;) are used for the pool lights, outdoor receptacles, and motor disconnects in the pump house.  A total of 9 Legrand 2087WCC4 were installed from 2020-2021.  This does not include 5 standard GFCI receptacles (tracked elsewhere).  GFCIs are said to last 10 years - but these units may last a significantly shorter period due to the corrosive environment in which they are installed.  &amp;lt;b&amp;gt;These GFCI devices in particular MUST be regularly tested as they provide critical protection to pool occupants.&amp;lt;/b&amp;gt;  The 2021 replacement cost for each is approximately $20 (may find for less in bulk or as a surplus buy).&lt;br /&gt;
|-&lt;br /&gt;
|Motor (Main Pump)&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|&lt;br /&gt;
|$1,700&lt;br /&gt;
|&lt;br /&gt;
|$2,200&lt;br /&gt;
|The main pump motor is a 15 HP 230 VAC unit, as detailed [[Pool Main Pump Motor|here]].&lt;br /&gt;
|-&lt;br /&gt;
|Pump (Main)&lt;br /&gt;
|1995&lt;br /&gt;
|Unknown&lt;br /&gt;
|30&lt;br /&gt;
|Unknown&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The installation date of the pump is not known; estimated to be from the mid-&#039;90s based on word of mouth.  The impeller and seals should be replaced every 20-40 years; it is likely due for maintenance soon.&lt;br /&gt;
|-&lt;br /&gt;
|Pump (Slide)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|The slide pump is a Grundfos Alpha1 15-55SF/LC (99287250) stainless steel circulation pump (1/16 HP).  The replacement (an Alpha2 15-55SF/LC, 99163972) is about $315 in 2021 (may be cheaper on surplus).  Circulation pumps are cited to last 10 years - but as always, subject to environment and use.&lt;br /&gt;
|-&lt;br /&gt;
|Piping (Post Pump)&lt;br /&gt;
|2021&lt;br /&gt;
|-&lt;br /&gt;
|Piping (Pre Pump)&lt;br /&gt;
|-&lt;br /&gt;
|Piping (Surge Tank)&lt;br /&gt;
|-&lt;br /&gt;
|Pool Vacuum&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The pool vacuum is a Power Vac Corporation Model #PV2100.  The date of manufacture and estimated lifespan are still TBD.  The replacement cost is about $900 in 2021.  Consider a PV2200 when replacement is due?&lt;br /&gt;
|-&lt;br /&gt;
|Pool Vacuum Battery&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Probe (pH)&lt;br /&gt;
|2022&lt;br /&gt;
|&lt;br /&gt;
|2&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$140&lt;br /&gt;
|$160&lt;br /&gt;
|$180&lt;br /&gt;
|$200&lt;br /&gt;
|Typically, the [[Chemtrol_Pool_Controller#Chemical_Probes|pH probes]] are rated to last a year.  However, with proper maintenance, [[Probe Calibration|calibration]] and off-season storage, it&#039;s assumed they&#039;ll last 2-3 years.  The cost of calibration reagent(s) is not included here, though should be considered with the chemical costs.  A new probe was installed in 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Probe (ORP)&lt;br /&gt;
|2022&lt;br /&gt;
|&lt;br /&gt;
|2&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$220&lt;br /&gt;
|$240&lt;br /&gt;
|$280&lt;br /&gt;
|$310&lt;br /&gt;
|Typically, the [[Chemtrol_Pool_Controller#Chemical_Probes|ORP probes]] are rated to last a year.  However, with proper maintenance, [[Probe Calibration|calibration]] and off-season storage, it&#039;s assumed they&#039;ll last 2-3 years.  A new probe was installed in 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Roof&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|Unknown&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|The date of installation is not known.  Repairs to the roof were made in 2021 to address a leak around the exhaust fan.  The roofer noted that 3 layers are present - this may result in added labor/disposal cost.  The roof is in serviceable condition for now (2021).  Plan on replacement in 10 years.&lt;br /&gt;
|-&lt;br /&gt;
|Sump Pump&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$300&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Surge Tank&lt;br /&gt;
|1967&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$36,800&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|As of 2021, the [[Pool_Systems_Introduction#Surge_Tank|surge tank]] is overdue for an overhaul.  The tank in its present state is &amp;quot;severely deteriorated&amp;quot;, leaking, and lacking essential functionality presumably removed via low-budget modifications.  The cost for a full overhaul is estimated at $36,800 and must be performed when the pool is empty.&lt;br /&gt;
|-&lt;br /&gt;
|Variable Frequency Drive (VFD) for Main Pump Motor&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|10&lt;br /&gt;
|&lt;br /&gt;
|$1,200&lt;br /&gt;
|&lt;br /&gt;
|$1,500&lt;br /&gt;
|The main pump motor VFD is a Yaskawa GA50U2042ABA and was installed in 2022.  The lifespan is an estimate - and is subject to many variables.  Exposure to chemical vapors (chlorine, acid) and excess heat will reduce the lifespan.  Efforts have been made to limit exposure to both.  NOTE: The VFD has been shown to reduce club energy use by about 20 % (savings of $200-$300 a month in 2022).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Snack Shack ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Air Conditioner (Heat Pump)&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|12&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|The air conditioner (heat pump) is a single-zone, 18,000 BTU 230 V &amp;quot;mini-split&amp;quot; unit.  The indoor unit is LG p/n LSN180HEV2, and the outdoor unit is LG p/n LSU180HEV2.  Lifespan estimates place heat pumps at 10-15 years.  The replacement cost is not known.  NOTE: This unit was installed primarily to reduce the burden on the refrigeration units in the snack shack, which would often operate 24/7 during hot periods of the summer.&lt;br /&gt;
|-&lt;br /&gt;
|Drywall (Ceiling)&lt;br /&gt;
|2019&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The snack shack ceiling was replaced in 2019 due to failure (collapse).  There is no anticipated need to replace again at this time (at least not within the 20 year planning period).&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|15&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|The exhaust fan is a Broan L700.  Starting in 2022, its usefulness going forward will be greatly reduced due to the installation of the A/C unit.  &lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2019&lt;br /&gt;
|2021&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|$60&lt;br /&gt;
|$140&lt;br /&gt;
|$80&lt;br /&gt;
|$190&lt;br /&gt;
|Six-year maintenance ($38 in 2021 dollars) is due in 2025 and 2031.  Replacement ($90 in 2021 dollars) is due in 2031.  Annual servicing ($6 in 2021 dollars) is required.  Prices adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Ice Cream)&lt;br /&gt;
|2012&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|10&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$1,200&lt;br /&gt;
|&lt;br /&gt;
|The &amp;quot;Blue Bunny Ice Cream&amp;quot; freezer is a model 46SLC-LH-MFB, built in 2012.  The replacement cost is estimated to be $900 (an Avantco DFC16-HCL in 2021 dollars, adjusted for inflation in 2032).  Past experience during a power outage suggests that these units are not particularly well insulated.  A better replacement may be desired when the 20 year estimated lifespan (2032) arrives.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Upright)&lt;br /&gt;
|2014&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|12&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|$4,100&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a Supera F1R-1, DOM: 30-Mar-2014.  Last checked out by a refrigeration contractor in 2021.  The Supera brand is not well known/respected and may not last within the typical 15-20 year lifespan cited for commercial kitchen refrigeration units.  Repair parts may not be available (Supera appears to be defunct).  The estimated replacement cost is based upon an equivalent True unit.&lt;br /&gt;
|-&lt;br /&gt;
|Garbage Disposal&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|The installation date of the garbage disposal is not known at this time.&lt;br /&gt;
|-&lt;br /&gt;
|Microwave #1&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|$500&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a Sunbeam SGB8901.  This is a residential unit, and is over-stressed by high duty cycle use.  The average residential microwave is said to last 7 years - the estimate has been reduced to 5 as an estimate per the part-time heavy use.  The estimated replacement cost is based upon the purchase of a commercial microwave, better suited for the purpose.&lt;br /&gt;
|-&lt;br /&gt;
|Microwave #2&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|$500&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a Samsung MS11K3000AS.  This is a residential unit, and is over-stressed by high duty cycle use.  The average residential microwave is said to last 7 years - the estimate has been reduced to 5 as an estimate per the part-time heavy use.  The estimated replacement cost is based upon the purchase of a commercial microwave, better suited for the purpose.&lt;br /&gt;
|-&lt;br /&gt;
|Refrigerator&lt;br /&gt;
|1997&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$500&lt;br /&gt;
|$500&lt;br /&gt;
|$4,600&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a True T-23, DOM: 1-May-1997.  Last checked out by a refrigeration contractor in 2021.  Setting aside $500 in 1-5 years and $500 in 5-10 years for repairs, replacement with another a True unit in 10-15 (unit will be nearly 40 years old).  No known issues with the existing unit other than it is 24 years old (as of 2021), exceeding the expected lifespan.  That said - given the seasonal use, it may last longer.  A True unit is highly repairable (as long as the fundamentals such as the cabinet are sound).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Women&#039;s Restroom ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fans (Small)&lt;br /&gt;
|Unknown&lt;br /&gt;
|N/A&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are two small exhaust fans in the women&#039;s restroom.  The larger of the two (13&amp;quot; assumed) is missing, the smaller (9&amp;quot; assumed) is in place, but non-functional (motor seized).  Replacement is recommended as soon as the budget permits (cost to be determined).&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan (Large)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The exhaust fan in the women&#039;s restroom is in poor condition.  Replacement is recommended as soon as the budget permits (cost to be determined).&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Asset_Registry&amp;diff=1765</id>
		<title>Asset Registry</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Asset_Registry&amp;diff=1765"/>
		<updated>2025-01-04T12:48:23Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Asset Registry is maintained by Building &amp;amp; Grounds and reviewed by the board.  The original version was created by Sally Duffy and the 2020 Capital Assessment Committee.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Last Updated:&amp;lt;/b&amp;gt; January 4th, 2025&lt;br /&gt;
&lt;br /&gt;
Where possible, inflation is considered (using [https://smartasset.com/investing/inflation-calculator this calculator], for instance).  Future investment is a &amp;quot;best guess&amp;quot; based upon past quotes or work, where possible.  NOTE: A higher-than-expected inflation rate took effect in 2022.  This has not necessarily been factored into calculations (August 2022).  Many estimates were made in 2020 and 2021.&lt;br /&gt;
&lt;br /&gt;
Columns for &amp;lt;b&amp;gt;Failure Mode and Effect Analysis (FMEA)&amp;lt;/b&amp;gt; were added in January 2023.  The columns are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Severity (S):&amp;lt;/b&amp;gt; 1 = insignificant (minimal operational impact); 10 = catastrophic (the club cannot operate)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Occurrence (O):&amp;lt;/b&amp;gt; 1 = extremely unlikely; 10 = inevitable&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Detection (D):&amp;lt;/b&amp;gt; 1 = certain to detect; 10 = certain not to detect&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Risk Priority Number (RPN):&amp;lt;/b&amp;gt; The product of O, S and D.  0 = low risk; 1000 = highest risk&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FMEA Values are subjective.  The threshold of concern (for the RPN) is generally set to 200, though subject to revision.&lt;br /&gt;
&lt;br /&gt;
== Basement ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable mw-collapsible&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|FMEA&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2025)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
!S&lt;br /&gt;
!O&lt;br /&gt;
!D&lt;br /&gt;
!RPN&lt;br /&gt;
|-&lt;br /&gt;
|Breaker Panel ([[Electrical System#Basement Panel RLP-2|RLP-2]])&lt;br /&gt;
|1966&lt;br /&gt;
|2020&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|10&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|100&lt;br /&gt;
|The basement breaker panel is a Square D QO series (copper bus bar).  It is in good operating condition.  No plans to replace it for the foreseeable future.  The wiring was cleaned up and the branch side lugs were properly torqued in 2020.  New circuits added.  Very limited capacity left - additional circuits should be added to the upstairs panel (RLP-1).&lt;br /&gt;
|-&lt;br /&gt;
|Circulator Pump (Hot Water)&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|6&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$420&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|25&lt;br /&gt;
|The hot water circulator pump is a Grundfos Alpha2 15-55SFC (99163937) stainless steel circulation pump (1/16 HP).  The replacement cost is $330 in 2021 (maybe cheaper on surplus).  Circulation pumps are cited to last ten years - but as always, subject to environment and use.  As of 2021/2022, it was noted that the circulation function didn&#039;t really work correctly (2021/2022).  In 2024, an aquastat was added to (finally) address the issues.&lt;br /&gt;
|-&lt;br /&gt;
|Dehumidifier &amp;quot;A&amp;quot;&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|0&lt;br /&gt;
|$330&lt;br /&gt;
|$380&lt;br /&gt;
|$420&lt;br /&gt;
|$480&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|3&lt;br /&gt;
|192&lt;br /&gt;
|The existing model is a Toshiba TDDP5012ES2 50pint/day unit (DOM: 08/2019, but not placed into service until 2020).  The replacement cost is $300.  Dehumidifiers tend to be short-lived (especially in high humidity, high-duty cycle environments).  It is estimated that this unit may only last five years.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;B&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; While the severity of a failure is high (mold growth, if not resolved), this unit is easily replaceable and poses no risk to the operating status of the club.&lt;br /&gt;
|-&lt;br /&gt;
|Dehumidifier &amp;quot;B&amp;quot;&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|3&lt;br /&gt;
|$340&lt;br /&gt;
|$380&lt;br /&gt;
|$430&lt;br /&gt;
|$490&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|3&lt;br /&gt;
|192&lt;br /&gt;
|The existing model is a Frigidaire (Electrolux) FGAC7044U101 (DOM: 01/2019, but not placed into service until 2021).  The replacement cost is $300.  See the comments for &amp;lt;b&amp;gt;Dehumidifier &amp;quot;A&amp;quot;&amp;lt;/b&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|6&lt;br /&gt;
|$30&lt;br /&gt;
|$180&lt;br /&gt;
|$40&lt;br /&gt;
|$230&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The basement fire extinguisher is a Buckeye ABC unit (exact model TBD).  Six-year maintenance ($38 in 2021 dollars) is due in 2027 and 2037 (was originally due in 2023 per manufacture date but occurred in 2021).  Replacement ($90 in 2021 dollars) is due in 2029 and 2041.  Annual servicing ($6 in 2021 dollars) is required.  Prices are adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Foundation/Walls&lt;br /&gt;
|1966&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|18&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|$16,000&lt;br /&gt;
|7&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|175&lt;br /&gt;
|Installed a new internal weeping tile system and sump pump in 2021.  Assume that after 20 years, the system may need to be replaced (again) due to the eventual infiltration of sediment.  Painted basement walls with Liquid Rubber and Drylok in 2021.  Hydrostatic pressure is causing a bulge on the east wall (near the staircase).  TBD cost to address in the 5-10 year window (as of 2021) unless movement/cracking makes the project more urgent.  As of 2022, some breakdown is visible in the corners (discoloration, visible water).  This may be corrected on a spot basis.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Chest)&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|20&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|8&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|32&lt;br /&gt;
|The existing model is a Kelvinator Commercial KCCF170WH (59 1/2&amp;quot;, 17 cu ft capacity).  The date of manufacture is not known.  The replacement cost in 2021 is about $930.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Chest)&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|14&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$1,300&lt;br /&gt;
|8&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|32&lt;br /&gt;
|The existing model is an Electrolux KCCF160QWA commercial freezer (15.58 cu ft capacity).  This model does not appear to be made anymore; replacement with a KCCF170WH or equivalent (replacement cost in 2021 is about $930; about $1,300 in 2036 with inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Ice Cream)&lt;br /&gt;
|2010&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|Failed&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&amp;lt;b&amp;gt;2023 Update:&amp;lt;/b&amp;gt; This unit has been identified to have failed in the prior year and is subject to replacement.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Blue Bunny Ice Cream&amp;quot; freezer is a model RIO S125, built in 2010.  The replacement cost is estimated at $900 (an Avantco DFC16-HCL in 2021 dollars, adjusted for inflation in 2030).  Experience during a power outage suggests that these units are poorly insulated.  A better replacement may be desired when the 20-year estimated lifespan (2030) arrives.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Upright)&lt;br /&gt;
|2013&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|11&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|8&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|32&lt;br /&gt;
|The existing model is a Whirlpool EV161NZTQ02 household freezer.  The replacement cost is not known at this time.&lt;br /&gt;
|-&lt;br /&gt;
|Main Distribution Panel&lt;br /&gt;
|1966&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|10&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|100&lt;br /&gt;
|The distribution panel was informally inspected in 2021.  No signs of issues.  No plans for service or replacement soon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;B&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; Regular inspections are required.&lt;br /&gt;
|-&lt;br /&gt;
|Network Equipment&lt;br /&gt;
|2020&lt;br /&gt;
|2022&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|5&lt;br /&gt;
|3&lt;br /&gt;
|2&lt;br /&gt;
|30&lt;br /&gt;
|Some equipment replacement is anticipated every five years due to product end-of-life (EOL), failures, or technology upgrades.  The cost is not known at this time.  A new PoE network switch was installed in the clubhouse in 2022.  NOTE: For the sake of security, specifics about the network are not posted on the Wiki.&lt;br /&gt;
|-&lt;br /&gt;
|Sump Pump&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$300&lt;br /&gt;
|&lt;br /&gt;
|7&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|175&lt;br /&gt;
|The sump pump is a Foundation Systems of Michigan (FSM) Elite 365 AquaStop Sump Pump System (1/3 HP).  Replacement after ten years is anticipated.&lt;br /&gt;
|-&lt;br /&gt;
|Tempering Valve&lt;br /&gt;
|2020&lt;br /&gt;
|2021&lt;br /&gt;
|8&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|6&lt;br /&gt;
|&lt;br /&gt;
|$5,300&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|5&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|50&lt;br /&gt;
|The tempering valve is a Powers LFMM 433-13 (1-1/4&amp;quot; 110 GPM).  This part number (as written in the plumbing invoice) needs to be confirmed; the -13 suffix doesn&#039;t seem to align with an actual part number.  Tempering valves are cited to last 5-8 years in general.  The impact of seasonal use is TBD.  As of 2021, the functionality of the tempering valve and its interaction with the hot water circulation pump has been problematic.  An additional effort may be required in 2022.  The temperature/pressure gauge failed in 2021 and was replaced with a Watts WLFDPTG330200D.  The material and labor cost in 2020 was about $5,300; replacement in 2028 adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|UPS Batteries (Network)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$60&lt;br /&gt;
|$70&lt;br /&gt;
|$80&lt;br /&gt;
|$90&lt;br /&gt;
|3&lt;br /&gt;
|6&lt;br /&gt;
|3&lt;br /&gt;
|54&lt;br /&gt;
|The network battery backup is an APC Smart-UPS SMC1500-2U.  It uses four [https://www.power-sonic.com/product/ps-1270/ PS-1270] lead-acid batteries (the replacement cost for the Power-Sonic brand is $13 each from a local distributor).&lt;br /&gt;
|-&lt;br /&gt;
|Water Heater&lt;br /&gt;
|2007&lt;br /&gt;
|2018&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$20,000&lt;br /&gt;
|&lt;br /&gt;
|$27,000&lt;br /&gt;
|&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|512&lt;br /&gt;
|The [domestic hot] water heater is confirmed to have been installed in 2007, both by the serial number and the permit pulled noted in [[Club History#2007|club history]].  The existing unit is a Lochinvar TNR200-100 (100-gallon) fully condensing water heater.  The standard &amp;quot;rule of thumb&amp;quot; is to pre-emptively replace a water heater at the 10-year mark.  However, the fact that the water heater is drained and dormant from about September to April should have some longevity benefits.  Replacement is assumed to be necessary within the 5-10 year span (as of 2021), if not earlier.  The replacement cost is based on a quote received for labor and materials in early 2023.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; It is assumed that the domestic hot water heater is critical to club operation (for health code reasons), and the club cannot operate without it.  Detecting a failure is difficult (water heaters often fail with little to no warning once they cross the decade-old mark).  Failure is more or less &amp;quot;inevitable&amp;quot; for a residential-grade unit.  It&#039;s not clear how the commercial-grade unit differs.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basketball and Tennis Courts ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|FMEA&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2023)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
!S&lt;br /&gt;
!O&lt;br /&gt;
!D&lt;br /&gt;
!RPN&lt;br /&gt;
|-&lt;br /&gt;
|Basketball Poles&lt;br /&gt;
|2018&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|20&lt;br /&gt;
|Lifespan, replacement plans, and replacement cost are TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Surface (Basketball)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|$38,000&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are essentially four options given the court conditions:&lt;br /&gt;
# Powerwash to clean.  Fill cracks with acrylic crack filler, then resurface and paint for about $20,000.  Based on just short of 900 ft of cracks at 2020 pricing.  This is a very short-term solution; assume cracks will re-appear after a large day/night temperature swing (and especially after a freeze/thaw).  For that reason, this repair is not recommended.&lt;br /&gt;
# The same as the prior option, plus fabric overlay crack repair (2-year guarantee) for about $33,000.  This solution should last 4-5 years (after which cracks may re-appear).  This may be the best solution for the near term.  For this option, the sport coating contractor may be hired directly.&lt;br /&gt;
# Grind down 2 inches of the surface, then re-build for about $100,000 ($50,000 per court).  For this option, hire a paving contractor; the sport coating is subcontracted.&lt;br /&gt;
# Demolish, add improved drainage, then rebuild for about $150,000 ($75,000 per court).  This is by far the most expensive, but the most effective solution depending upon the underlying issues (i.e. very wet grounds).  For this option, hire a paving contractor; the sport coating is subcontracted.&lt;br /&gt;
Given current budgets, it seems likely that option #2 is the best choice for the 5-10 year window.  The lifespan of 5 years assumes repeated use of option #2.&lt;br /&gt;
|-&lt;br /&gt;
|Surface (Tennis)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|$42,000&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are essentially four options given the court conditions:&lt;br /&gt;
# Powerwash to clean.  Fill cracks with acrylic crack filler, then resurface and paint per USTA standards for about $23,000.  Based on just short of 1000 ft of cracks at 2020 pricing.  This is a very short-term solution; assume cracks will re-appear after a large day/night temperature swing (and especially after a freeze/thaw).  For that reason, this repair is not recommended.&lt;br /&gt;
# The same as the prior option, plus fabric overlay crack repair (2-year guarantee) for about $37,000.  This solution should last 4-5 years (after which cracks may re-appear).  This may be the best solution for the near term.  For this option, the sport coating contractor may be hired directly.&lt;br /&gt;
# Grind down 2 inches of the surface, then re-build for about $100,000 ($50,000 per court).  For this option, hire a paving contractor; the sport coating is sub-contracted.&lt;br /&gt;
# Demolish entirely, add improved drainage, then re-build for about $150,000 ($75,000 per court).  This is by far the most expensive, but the most effective solution depending upon the underlying issues (i.e. very wet grounds).  For this option, hire a paving contractor; the sport coating is sub-contracted.&lt;br /&gt;
Given present budgets, it seems likely that option #2 is the best choice for the 5-10 year window.  The lifespan of 5 years assumes repeated use of option #2.&lt;br /&gt;
|-&lt;br /&gt;
|Tennis Nets&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|New Edwards 30LS &amp;quot;Wimbledon Nets&amp;quot; were purchased in late 2021 and installed in the spring of 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Tennis Pole Hardware&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|$150&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The age of the existing poles is not known.  In 2022, two new &amp;quot;53420-B EZ Tennis Post Replacement Reels&amp;quot; from &amp;quot;Tennis Court Supply&amp;quot; were installed.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Clubhouse ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2023)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|Awning&lt;br /&gt;
|1997&lt;br /&gt;
|2020&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|It appears (but has not been confirmed) that the awning was installed in 1997.  The fabric material is assumed to be Sunbrella, with a 10-year rated lifespan.  However, 24 years later (as of 2021), it still looks good.  The fabric was cleaned per manufacturer recommendations in 2020.  No planned replacement until it is aesthetically necessary.&lt;br /&gt;
|-&lt;br /&gt;
|Breaker Panel ([[Electrical System#Basement Panel RLP-1|RLP-1]])&lt;br /&gt;
|2007&lt;br /&gt;
|2022&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The &amp;quot;upstairs&amp;quot; panel was added in [[Club History#2007|2007]] presumably to support additional circuits (hand dryers, etc).  There are no plans to replace it in the 20-year window.  The panel was last serviced in 2022.  Lug torques were verified, and new circuits were added.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;FMEA Note:&amp;lt;/b&amp;gt; Regular inspections are required to meet the &amp;quot;detection&amp;quot; value.&lt;br /&gt;
|-&lt;br /&gt;
|Changing Table&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|17&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The baby changing station is a Koala Kare KB200 (replacement cost is $210 based on average online pricing as of 2021).  The lifespan is a guess and may be adjusted depending on observations of wear and tear in future years.  There is no planned replacement within the 20-year window (as of 2023).&lt;br /&gt;
|-&lt;br /&gt;
|Chimney&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The chimney is most likely original to the 1966 structure.  It is functionally obsolete; the only device producing combustion gases in the clubhouse is vented via PVC pipe.  Unfortunately, the mortar appears to be failing.  Tuckpointing is recommended shortly.  Alternatively, the chimney could potentially be removed.&lt;br /&gt;
|-&lt;br /&gt;
|Computer&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|3&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|A regular refresh cycle for the front-desk computer is planned.  The replacement cost is TBD (donated/retired business PCs preferred).&lt;br /&gt;
|-&lt;br /&gt;
|Drywall (Family Restroom Ceiling)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The family restroom ceiling was replaced in 2020 upon discovery that it was sagging several inches in the middle of the room.  No replacement is planned.&lt;br /&gt;
|-&lt;br /&gt;
|Drywall (Lobby Ceiling)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Repairs were made to the drywall near the north end (to address sagging) during the 2022 lobby renovation.  At this time, it was observed that repairs had previously been made near the &amp;quot;Fairway Farms&amp;quot; glass by the stairs.  No replacement is planned.&lt;br /&gt;
|-&lt;br /&gt;
|Electrical&lt;br /&gt;
|1966&lt;br /&gt;
|2020&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|7&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&amp;lt;p&amp;gt;Much of the wiring in the clubhouse is original to the 1966 installation.  Fortunately, #12 AWG copper was run in rigid conduit throughout.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;In 2020, the wiring was inspected and found in good condition.  Nearly all receptacles, switches, and fixtures were replaced.  All associated connections (screws, wire nuts) were removed, cleaned of oxidation, and re-terminated.  Wiring in panels ([[Electrical System#Basement Panel RLP-1|RLP-1]] and [[Electrical System#Basement Panel RLP-2|RLP-2]]) was cleaned up, and all branch-side lugs were torqued to spec.&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;The basement switchgear was inspected and deemed to be in good operating condition (no replacement planned).&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Replacement of certain receptacles, switches, and fixtures may be needed on a 10-year interval.  The cost is TBD.&amp;lt;/p&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Exit Signs&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$80&lt;br /&gt;
|$90&lt;br /&gt;
|$100&lt;br /&gt;
|$120&lt;br /&gt;
|The lifespan of the two exit signs is largely determined by the ability of the internal rechargeable batteries to sustain 90 minutes of illumination upon power failure.  This is an annual city inspection requirement (Livonia Code of Ordinances 15.32.030).  The battery pack may be replaceable.  If not, off-brand exit signs with floodlights can be had for as little as $40 (or less) on Amazon.&lt;br /&gt;
|-&lt;br /&gt;
|Fans (Pedestal)&lt;br /&gt;
|1995&lt;br /&gt;
|None&lt;br /&gt;
|50&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|22&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are two pedestal fans in the clubhouse.  One appears to be from 1995; the date of manufacture for the other is unknown (TBD).  The fans are anticipated to last beyond the 20-year view (as of 2021). Minor repairs may be needed; the cost is TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2016&lt;br /&gt;
|2020&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|$70&lt;br /&gt;
|$140&lt;br /&gt;
|$80&lt;br /&gt;
|$180&lt;br /&gt;
|The clubhouse (lobby) fire extinguisher is an Advantage ADV-10, as of 2021, last serviced in May 2020 (per punch tag).  Six-year maintenance ($38 in 2021 dollars) is assumed to be due in 2022 and 2034. Replacement ($90 in 2021 dollars) is due in 2028 and 2040. Annual servicing ($6 in 2021 dollars) is required. Prices are adjusted for inflation. &lt;br /&gt;
|-&lt;br /&gt;
|Floor&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Any rehabilitation or replacement of the floor in the clubhouse (main floor) is yet to be discussed.  The original installation date is not known.&lt;br /&gt;
|-&lt;br /&gt;
|Gutters&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Gutters are in disrepair (leaking) and should be replaced.  The plan is for the 5-10 year window (as of 2021).  We received quotes in 2020 that need to be located for reference.&lt;br /&gt;
|-&lt;br /&gt;
|Hand Dryers&lt;br /&gt;
|2007&lt;br /&gt;
|None&lt;br /&gt;
|25&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|The existing American Dryer (Global Dryer) model GX1 units were installed in [[Club_History#2007|2007]].  Lifespan is a guess.  The estimated cost is for two replacement units in 2032 ($150/ea in 2021 prices).  Labor is not included.&lt;br /&gt;
|-&lt;br /&gt;
|Lights (Vapor-Proof)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|16&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|The fixtures are TOGGLED FV420PO-A423-40230 (includes 2 x 4000K 23 W 3,100 lumen bulbs).  The replacement cost in 2021 is about $65 per fixture.  TOGGLED rates the bulbs for 16 years (subject to vary based on exposure and usage).  No replacement cost is given for 2036, as technology may dictate a different solution.&lt;br /&gt;
|-&lt;br /&gt;
|PA Amplifier&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|17&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$1,300&lt;br /&gt;
|The amplifier&#039;s lifespan is based upon many factors; 20 years is an educated guess.  The biggest enemies to its longevity are excessive heat, dirt infiltration, and condensation.  Keeping the amplifier cool and clean is critical.  Often amplifiers fail due to their power supply capacitors failing; these may or may not be replaceable (the unit may be serviceable).  The cost is an estimate based on the retail cost of the existing JBL CSMA 2120, plus inflation, in 2040.&lt;br /&gt;
|-&lt;br /&gt;
|Radios&lt;br /&gt;
|2013&lt;br /&gt;
|2021&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$80&lt;br /&gt;
|$95&lt;br /&gt;
|$110&lt;br /&gt;
|$120&lt;br /&gt;
|There are six Motorola MH230R FRS/GMRS radios in the clubhouse, used for grounds-wide communication.  Four radios were purchased in 2021 to match the existing two units on hand.  New &amp;quot;old stock&amp;quot; KEBT-086-C batteries were installed in 2021.  Three charging stations are used to trickle-charge the NiMH battery packs.  Based on observations in 2021, these radios are used and abused quite hard; regular replacement is assumed.  Assume a replacement cost of $80 for two radios per 5-year interval, adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;div id=&amp;quot;0001&amp;quot;&amp;gt;Roof&amp;lt;/div&amp;gt;&lt;br /&gt;
|2014&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|11&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The assumption is that the clubhouse roof was replaced in [[Club History#2014|2014]].&lt;br /&gt;
|-&lt;br /&gt;
|Steel Doors&lt;br /&gt;
|1966&lt;br /&gt;
|Unknown&lt;br /&gt;
|30&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$8,200&lt;br /&gt;
|&lt;br /&gt;
|$8,000&lt;br /&gt;
|&lt;br /&gt;
|The steel doors appear to be original to the building.  There are nine doors in total: two for the lobby exterior, two for the family restroom, three for the men&#039;s room, and two for the women&#039;s room.  It has been proposed to replace the two exterior restroom doors and the interior men&#039;s room door as soon as possible.  Then, replace the two doors between the men&#039;s and women&#039;s room and lobby in five years or less.  The other exterior and interior doors may need to be replaced in 10-15 years.  Costs are based on estimates received in 2023.&lt;br /&gt;
|-&lt;br /&gt;
|Showers&lt;br /&gt;
|TBD&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Soffit&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The wooden soffit is in disrepair and needs replacement with a low-maintenance product.  The venting grate is failing and has allowed animal intrusion.  The replacement should coincide with gutter (and possible fascia) replacement.  No estimates have been made at this point.&lt;br /&gt;
|-&lt;br /&gt;
|Toilets&lt;br /&gt;
|TBD&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The installation date of the toilets is not known.  NOTE: Toilet valves are a separate topic.&lt;br /&gt;
|-&lt;br /&gt;
|Toilet Valves&lt;br /&gt;
|1966&lt;br /&gt;
|2021&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|3&lt;br /&gt;
|$1,100&lt;br /&gt;
|$1,300&lt;br /&gt;
|$1,400&lt;br /&gt;
|$1,600&lt;br /&gt;
|Numerous toilet valves were replaced in 2021.  Some additional refurbishment in 2022 (this is an annual need).  Rebuild kits may work; replacement is suggested after numerous rebuilds.&lt;br /&gt;
|-&lt;br /&gt;
|UPS Batteries (Front Desk)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$30&lt;br /&gt;
|$30&lt;br /&gt;
|$40&lt;br /&gt;
|$40&lt;br /&gt;
|The front desk battery backup is an APC Back-UPS XS 1500.  It uses two [https://www.power-sonic.com/product/ps-1270/ PS-1270] lead-acid batteries (the replacement cost for the Power Sonic brand is $13 each from a local distributor).&lt;br /&gt;
|-&lt;br /&gt;
|Windows (Exterior)&lt;br /&gt;
|1967&lt;br /&gt;
|None&lt;br /&gt;
|N/A&lt;br /&gt;
|N/A&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The exterior windows appear to be original to the facility (except for the newer exterior window in the Snack Shack).  No plans to replace.&lt;br /&gt;
|-&lt;br /&gt;
|Window Shutters&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Grounds ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2023)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|Fence (Property Line)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Patio Sets&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Discussion of replacement of the patio sets is pending.&lt;br /&gt;
|-&lt;br /&gt;
|Parking Lot&lt;br /&gt;
|2000&lt;br /&gt;
|2020&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$14,400&lt;br /&gt;
|$16,300&lt;br /&gt;
|$18,500&lt;br /&gt;
|$20,800&lt;br /&gt;
|The asphalt parking lot was first installed in 2000.  Maintenance is necessary every 5-7 years (largely subject to weather).  Maintenance was known to have been performed in [[Club History#2015|2015]] and 2020.  Costs for 2025, 2030, 2035, and 2040 are based on the prior estimate (for 2020) with inflation.  NOTE: There has been some discussion (Spring 2023) whether a complete re-surfacing may be required?  Cost might be as high as $100k?  To be discussed further.&lt;br /&gt;
|-&lt;br /&gt;
|Picnic Tables (Plastic)&lt;br /&gt;
|2007&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|A spot check of a few tables suggests that the entire lot may have been purchased (or at least manufactured) in 2007.  Some tables are starting to fail mechanically and have been temporarily repaired.  Some of the painted metal parts are flaking/rusting.  It likely makes the most sense to start purchasing a small number of tables to begin the replacement of the worst units over time - unless there is a substantial benefit from a bulk order.  The lifespan of 20 years is based on current wear and tear.  It seems possible that within 5 years (from 2022), the condition of some tables may be approaching &amp;quot;poor&amp;quot;.  To be determined.&lt;br /&gt;
|-&lt;br /&gt;
|Picnic Tables (Wooden)&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|2021&lt;br /&gt;
|Unknown&lt;br /&gt;
|$100&lt;br /&gt;
|$110&lt;br /&gt;
|$130&lt;br /&gt;
|$150&lt;br /&gt;
|Outright replacement of the wooden picnic tables (7 on the property as of 2021) is not anticipated.  Instead, periodic wood/hardware replacement and stripping/painting should keep the tables in good working order.  Predicting maintenance costs is difficult, given the volatile cost of lumber.  Assume $100 every 5 years, adjusted for inflation.  All tables were power-washed and painted in 2021.&lt;br /&gt;
|-&lt;br /&gt;
|Play Structure&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|The present Miracle Recreation play structure (and swing sets) were installed in 2016.  Miracle recommends playground updates every 8-10 years; playgrounds can last 10-20 or more years, dependent upon weather and usage.  An estimated replacement date of 20 years is given, though the equipment may last longer.  Regular inspections must be performed.  Assume some maintenance cost within 5-10 years (from 2021).&lt;br /&gt;
|-&lt;br /&gt;
|Privacy Fence&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Installed in 2020, minor repairs in 2021.&lt;br /&gt;
|-&lt;br /&gt;
|Shed&lt;br /&gt;
|1986&lt;br /&gt;
|2021&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The shed was installed in 1986.  A new roof, siding (west side), and doors were installed in 2021.&lt;br /&gt;
|-&lt;br /&gt;
|Speakers&lt;br /&gt;
|2020&lt;br /&gt;
|-&lt;br /&gt;
|Water Gate Valve&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|40&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|37&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The prior gate valve lasted about 40 years before showing issues; it is assumed that the [[Water Gate Valve#History|new gate valve]] will have a similar lifespan.  No planned maintenance or replacement prior to 2061.&lt;br /&gt;
|-&lt;br /&gt;
|WiFi APs&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$380&lt;br /&gt;
|$420&lt;br /&gt;
|$480&lt;br /&gt;
|$540&lt;br /&gt;
|The present APs were installed in 2020 and are fully supported as of 2021.  An estimated life of 5 years is given, largely due to the likelihood that the product will go EOL by then.  2 of the 3 APs are mounted outdoors, and the 3rd exists in a non-climate-controlled building (clubhouse).  The APs are powered year-round to help drive off potential internal condensation.  Still, exposure may reduce their lifespan.  If the product is still supported after the 5-year mark (2025), and the units are functional, an evaluation of the performance vs. a replacement should be considered.  The replacement cost in 2021 is $125/ea (3 units).  A replacement cycle of 5 years is assumed (units may remain in service longer).&lt;br /&gt;
|-&lt;br /&gt;
|Volleyball Net&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|3&lt;br /&gt;
|&lt;br /&gt;
|$220&lt;br /&gt;
|$250&lt;br /&gt;
|$280&lt;br /&gt;
|The decision to purchase a more durable volleyball net in 2021 appears to have been a good one; the net held up well for the whole season (versus cheaper nets that had to be replaced sometimes multiple times per season).  A lifespan of 5 years is anticipated, as UV will eventually break down the vinyl.  The existing net is a [https://www.volleyballusa.com/hd2-heavy-duty-volleyball-net/ VolleyballUSA HD2].  The replacement cost is $200, adjusted for inflation on a 5-year interval.  &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Large Pavilion ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Ceiling Fans&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$640&lt;br /&gt;
|&lt;br /&gt;
|The ceiling fans (2) are Home Decorators Collection Windward 68-in units (Home Depot SKU #1004794977).  The replacement cost as of 2021 is $249/ea (adjusted to $320/ea for 2030).  An estimated lifespan of 10 years is predicted (assuming proper off-season storage per B&amp;amp;G standard procedure).  An equivalent replacement should be as large as possible (i.e. 68-in diameter) and with integrated LED lighting.&lt;br /&gt;
|-&lt;br /&gt;
|Roof&lt;br /&gt;
|2008&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The roof is assumed to be original to pavilion construction in [[Club History#2008|2008]].  It was noted by a contractor performing repairs in 2021 that the shingles&#039; spacing is incorrect.  The repair was made to match the improper spacing.&lt;br /&gt;
|-&lt;br /&gt;
|Gas Grills&lt;br /&gt;
|2012&lt;br /&gt;
|2020&lt;br /&gt;
|30&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|21&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|Lifespan is a guess.  Installed in 2012.  Grills were largely rebuilt/refurbished in 2020.  Replacement parts should keep them going for the foreseeable future.  Maintenance costs are TBD.  NOTE: Additional maintenance is planned during the off-season between 2022 and 2023.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Men&#039;s Restroom ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fans (Small)&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan (Large)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Projector&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The existing projector is a Viewsonic PJD555W (DLP 1280x800 WXGA, 20,000:1 contrast, 3,300 lumens).  It is discontinued by the manufacturer (as of 2017).  Lamp hours as of 2021 not know (lifespan is 5,000 hours).  Replacement may be desired to purchase a higher-lumen model to allow utilization before dusk (low priority).  A lifespan of 10 years has been assigned; it&#039;s assumed that by 2027, a replacement will be desired.  Movie nights in 2022 were hosted using member-provided equipment.&lt;br /&gt;
|-&lt;br /&gt;
|Projector Screen&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|This item is TBD.  Two &amp;quot;old&amp;quot; projector screens were removed and discarded in 2022.  A third (new-in-box) remains in the basement.  Movie nights in 2022 were hosted using member-provided equipment.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Pool ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Anchors (Backstroke Flags)&lt;br /&gt;
|Unknown&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|Unknown&lt;br /&gt;
|$250&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are four backstroke flag anchors in the pool deck.  The two anchors at the east end of the pool have failed and need to be replaced.  An estimated cost of $250 (2021 pricing) covers the cost of materials and tool rental (no labor cost).  NOTE: All four anchors may be replaced due to possible improper placement with respect to the ends of the pool.&lt;br /&gt;
|-&lt;br /&gt;
|Anchors (Starting Block)&lt;br /&gt;
|2018&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|18&lt;br /&gt;
|-&lt;br /&gt;
|Cover&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Need to determine the expected lifetime.  No replacement is planned in the 1-5 year term.&lt;br /&gt;
|-&lt;br /&gt;
|Diving Board&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|$6,500&lt;br /&gt;
|&lt;br /&gt;
|$8,300&lt;br /&gt;
|The diving board installed in 2020 is a Duraflex 16&#039; Modified Maxiflex Model &amp;quot;B&amp;quot;.  The replacement cost is estimated at $5,000 as of 2020.  Replacement is recommended every 7-10 years, but may vary due to outdoor/seasonal use.  Regular inspection is required to identify cracks or stress marks.&lt;br /&gt;
|-&lt;br /&gt;
|Drain Grates&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Drain grates have an expiration date.  Likely to be replaced during the pool renovation (2022).&lt;br /&gt;
|-&lt;br /&gt;
|Guard Stand (West)&lt;br /&gt;
|TBD&lt;br /&gt;
|2022&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The west guard stand appears to be a [https://www.spectrumproducts.com/stimson-lifeguard-chair-5-57308/ Spectrum Aquatics Stimson Lifeguard Chair (57308)].  A rough estimate for replacement cost is about $6,400.  The rotating base for the chair was replaced in 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Guard Stand (North)&lt;br /&gt;
|1990&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|It appears that the north guard stand, made by SR Smith, was installed in 1990.  No further information is available at this time.  No planned replacement or maintenance at this time (TBD).&lt;br /&gt;
|-&lt;br /&gt;
|Guard Umbrellas&lt;br /&gt;
|-&lt;br /&gt;
|Handrails&lt;br /&gt;
|-&lt;br /&gt;
|Ladders&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|$400&lt;br /&gt;
|$450&lt;br /&gt;
|$510&lt;br /&gt;
|$570&lt;br /&gt;
|There are 5 4-step ladders in the pool.  The original date of purchase is not known.  Most of the ladders appear to be of SR Smith make, though at least one ladder is an &amp;quot;Aquatech&amp;quot;.  Replacement of whole ladders is not anticipated.  Repairs (i.e., replacement steps/bolts) may be needed periodically.  As of 2020, an SR Smith ladder step with bolts costs about $50.  Anticipate replacement of two steps and two anchors (estimated at $250 in 2020) every five years.&lt;br /&gt;
|-&lt;br /&gt;
|Lane Markers&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|A Competitor brand 4&amp;quot; 25-meter racing lane (marker) cost is about $430 as of 2021.  There are 6 lanes in the pool (requiring 5 markers).  The age and condition of the existing markers is TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Marcite&lt;br /&gt;
|1966&lt;br /&gt;
|Unknown&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$100,000&lt;br /&gt;
|&lt;br /&gt;
|$128,000&lt;br /&gt;
|&lt;br /&gt;
|Pricing subject to further review; a budgetary estimate.  The plan for 2022 replacement is being developed [[Pool Marcite#Plan for 2022|here]].  Assume some amount of marcite replacement is necessary every 10 years.&lt;br /&gt;
|-&lt;br /&gt;
|Safety Ropes&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Two safety ropes (rope floats) are present in the pool:&lt;br /&gt;
* Between the &amp;quot;kiddie pool&amp;quot; and main pool (11 ft)&lt;br /&gt;
* Between the main pool and the diving well (27 ft)&lt;br /&gt;
Ropes were replaced with all-new parts for the 2022 season.&lt;br /&gt;
|-&lt;br /&gt;
|Slides&lt;br /&gt;
|2007&lt;br /&gt;
|2020&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|$10,200&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The south slide is an [https://www.srsmith.com/en-us/products/pool-slides/turbotwister/ SR Smith TurboTwister], the north slide is an [https://www.srsmith.com/en-us/products/pool-slides/typhoon/ SR Smith Typhoon].  The replacement cost is $4,000 and $2,900 based on average 2021 online pricing.  The installation date of the existing slides is unknown; a serial number suggesting 2008 appears on the Typhoon.  Both slides show signs of deterioration (superficial cracking as of 2021) and are targeted for replacement within 5-10 years.  Epoxy patching will be used in the meantime.  The replacement cost is estimated for 2028 and includes $2,000 for labor.  The listed lifespan is an estimate and based upon this target date.&lt;br /&gt;
|-&lt;br /&gt;
|Underwater Lights&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|Varies&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$6,600&lt;br /&gt;
|$1,000&lt;br /&gt;
|$1,000&lt;br /&gt;
|$7,000&lt;br /&gt;
|The proposal to retrofit pool lights is detailed [[Lighting#2022 Retrofit Proposal|here]].  $1,000 has been added to that cost to install new Aladdin rings during 2022.  $2,000 covers potential repairs/replacements through 2036, $7,000 has been estimated to replace the LEDs (best guess lifespan is about 15 years).&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Pool Deck ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Chairs&lt;br /&gt;
|Varies&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|Some regular chairs are in need of repair/replacement.  As of the manager&#039;s last accounting in 2021, of the 29 regular chairs, 9 are in need of repair.  Numbers to be confirmed.  A plan should be formed to begin staged replacement.  Coordination with other area clubs may be cost beneficial.&lt;br /&gt;
|-&lt;br /&gt;
|Concrete&lt;br /&gt;
|1967&lt;br /&gt;
|2018&lt;br /&gt;
|30&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|Portions of the concrete pool deck presumably date back to the original installation in [[Club History#1967|1967]].  Multiple repairs and deck replacements have been made since then.  As of 2021, the most recent work appears to have occurred in [[Club History#1998|1998]], [[Club History#2017|2017]] and [[Club History#2018|2018]].  Regular future maintenance is anticipated; the cost is TBD.&lt;br /&gt;
|-&lt;br /&gt;
|Fence&lt;br /&gt;
|2014&lt;br /&gt;
|-&lt;br /&gt;
|Funbrella&lt;br /&gt;
|TBD&lt;br /&gt;
|2022&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|A new crank mechanism from Anchor Industries (maker of the Funbrella) was purchased and installed in August 2022.  The prior crank mechanism had &amp;quot;worn out&amp;quot; its friction plate.  Further maintenance (hardware replacement) is planned for the structural portions.  The original installation date of the Funbrella is not known.&lt;br /&gt;
|-&lt;br /&gt;
|Lounges&lt;br /&gt;
|Varies&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|A significant number of the lounge chairs are in need of repair/replacement.  As of the manager&#039;s last accounting in 2021, of the 187 lounge chairs, 6 are not usable.  A significant number of the others are worn and should be replaced in the near future.  Numbers to be confirmed.  A plan should be formed to begin staged replacement.  Coordination with other area clubs may be cost beneficial.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Pump House ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Acid Pump&lt;br /&gt;
|2017&lt;br /&gt;
|Unknown&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The acid pump is a Stenner 45M5.  The replacement cost in 2021 is about $400.&lt;br /&gt;
|-&lt;br /&gt;
|Boiler&lt;br /&gt;
|2004&lt;br /&gt;
|2022&lt;br /&gt;
|10&lt;br /&gt;
|TBD&lt;br /&gt;
|$2,500&lt;br /&gt;
|$25,000&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|It is difficult to say how long the pool heater should last.  The plan (as of 2021) is to replace in 5-10 years.  Multiple inspections and component replacements were made in 2020, 2021 and 2022.  The heat exchanger was replaced around 2011 (the exact year is not known).  It is expected that some burners may need to be replaced around 2025-2026 ($2,500 or less).  Some references indicate that the pool heater may only last 10 years, but this is subject to several variables.&lt;br /&gt;
|-&lt;br /&gt;
|Breaker Panel ([[Electrical System#Basement Panel RLP-3|RLP-3]])&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The date of installation of the breaker panel in the pump house is not known.  No immediate plans are in place to replace it.  It should be noted that it utilizes an aluminum bus bar, which is inherently incompatible with the corrosive environment in which it exists.&lt;br /&gt;
|-&lt;br /&gt;
|Chlorinator Pump&lt;br /&gt;
|2013&lt;br /&gt;
|2022&lt;br /&gt;
|15&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|$300&lt;br /&gt;
|&lt;br /&gt;
|$540&lt;br /&gt;
|&lt;br /&gt;
|The chlorinator pump appears to be original to the chlorinator install (about 2013).  The shaft seal was replaced in 2021 and again in 2022.  The faceplate seal was replaced in 2022.  Prior to that, the shaft seal (and faceplate) were replaced in 2018.  The lifespan estimate has been bumped up to 13 years, though continued periodic maintenance of seals is expected.  It is a bit difficult to judge how long it may last, as it operates at a relatively low duty cycle but is exposed to super-chlorinated water and vapors.  The existing motor is a Hayward Century SP1515-Z-1-EFTC 1.5 HP pool pump.  The estimated replacement cost is $300.  Shaft seal replacement (parts and labor) costs about $100; the seals alone are significantly cheaper.&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|&lt;br /&gt;
|$180&lt;br /&gt;
|$200&lt;br /&gt;
|$220&lt;br /&gt;
|The exhaust fan is a Dayton 10N201 (1/6 HP 1400 CFM).  The thermostat circuit has been bypassed; the fan is intended to operate 24/7 when the pool is operating.  The estimated useful life is based upon an assumption that the chemical vapors may cause premature failure.  The fan may last significantly longer.&lt;br /&gt;
|-&lt;br /&gt;
|Filter Sand&lt;br /&gt;
|2013&lt;br /&gt;
|2021&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|1&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|The pool filter tank sand was last changed in [[Club History#2013|2013]].  For an outdoor pool, this generally should be done every 10 years (which can coincide with marcite replacement).  The cost is pending.  The sand was stirred in 2021 and 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|5&lt;br /&gt;
|&lt;br /&gt;
|$110&lt;br /&gt;
|$330&lt;br /&gt;
|$150&lt;br /&gt;
|The pump house fire extinguisher an Amerex model 240, filled with water and anti-freeze to suppress chemical fires.  Five-year maintenance ($100 in 2021) is due in 2026 and 2036 (installed in 2021).  Replacement ($260 in 2021) is due in 2031 (10 years).  Prices are adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Flow Meter (Bypass)&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Flow Meter (Output)&lt;br /&gt;
|-&lt;br /&gt;
|Garage Door&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|30&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|28&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|A new Ideal Door brand 8 ft x 7 ft white insulated (R-Value 6.5) garage door was installed in 2020.  Replacement is not anticipated until around 2050.  The replacement cost (in 2021 dollars) is about $400, excluding the cost of additional materials (hardware, trim, etc).  &lt;br /&gt;
|-&lt;br /&gt;
|GFCI Switches &lt;br /&gt;
|None&lt;br /&gt;
|2020&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|$220&lt;br /&gt;
|&lt;br /&gt;
|$290&lt;br /&gt;
|The GFCI switches in the pump house (also referred to as &amp;quot;dead front GFCI outlets&amp;quot;) are used for the pool lights, outdoor receptacles, and motor disconnects in the pump house.  A total of 9 Legrand 2087WCC4 were installed from 2020-2021.  This does not include 5 standard GFCI receptacles (tracked elsewhere).  GFCIs are said to last 10 years - but these units may last a significantly shorter period due to the corrosive environment in which they are installed.  &amp;lt;b&amp;gt;These GFCI devices in particular MUST be regularly tested as they provide critical protection to pool occupants.&amp;lt;/b&amp;gt;  The 2021 replacement cost for each is approximately $20 (may find for less in bulk or as a surplus buy).&lt;br /&gt;
|-&lt;br /&gt;
|Motor (Main Pump)&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|4&lt;br /&gt;
|&lt;br /&gt;
|$1,700&lt;br /&gt;
|&lt;br /&gt;
|$2,200&lt;br /&gt;
|The main pump motor is a 15 HP 230 VAC unit, as detailed [[Pool Main Pump Motor|here]].&lt;br /&gt;
|-&lt;br /&gt;
|Pump (Main)&lt;br /&gt;
|1995&lt;br /&gt;
|Unknown&lt;br /&gt;
|30&lt;br /&gt;
|Unknown&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The installation date of the pump is not known; estimated to be from the mid-&#039;90s based on word of mouth.  The impeller and seals should be replaced every 20-40 years; it is likely due for maintenance soon.&lt;br /&gt;
|-&lt;br /&gt;
|Pump (Slide)&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|8&lt;br /&gt;
|&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|The slide pump is a Grundfos Alpha1 15-55SF/LC (99287250) stainless steel circulation pump (1/16 HP).  The replacement (an Alpha2 15-55SF/LC, 99163972) is about $315 in 2021 (may be cheaper on surplus).  Circulation pumps are cited to last 10 years - but as always, subject to environment and use.&lt;br /&gt;
|-&lt;br /&gt;
|Piping (Post Pump)&lt;br /&gt;
|2021&lt;br /&gt;
|-&lt;br /&gt;
|Piping (Pre Pump)&lt;br /&gt;
|-&lt;br /&gt;
|Piping (Surge Tank)&lt;br /&gt;
|-&lt;br /&gt;
|Pool Vacuum&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The pool vacuum is a Power Vac Corporation Model #PV2100.  The date of manufacture and estimated lifespan are still TBD.  The replacement cost is about $900 in 2021.  Consider a PV2200 when replacement is due?&lt;br /&gt;
|-&lt;br /&gt;
|Pool Vacuum Battery&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Probe (pH)&lt;br /&gt;
|2022&lt;br /&gt;
|&lt;br /&gt;
|2&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$140&lt;br /&gt;
|$160&lt;br /&gt;
|$180&lt;br /&gt;
|$200&lt;br /&gt;
|Typically, the [[Chemtrol_Pool_Controller#Chemical_Probes|pH probes]] are rated to last a year.  However, with proper maintenance, [[Probe Calibration|calibration]] and off-season storage, it&#039;s assumed they&#039;ll last 2-3 years.  The cost of calibration reagent(s) is not included here, though should be considered with the chemical costs.  A new probe was installed in 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Probe (ORP)&lt;br /&gt;
|2022&lt;br /&gt;
|&lt;br /&gt;
|2&lt;br /&gt;
|style=&amp;quot;background:#FFEB9C|2&lt;br /&gt;
|$220&lt;br /&gt;
|$240&lt;br /&gt;
|$280&lt;br /&gt;
|$310&lt;br /&gt;
|Typically, the [[Chemtrol_Pool_Controller#Chemical_Probes|ORP probes]] are rated to last a year.  However, with proper maintenance, [[Probe Calibration|calibration]] and off-season storage, it&#039;s assumed they&#039;ll last 2-3 years.  A new probe was installed in 2022.&lt;br /&gt;
|-&lt;br /&gt;
|Roof&lt;br /&gt;
|Unknown&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|Unknown&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|The date of installation is not known.  Repairs to the roof were made in 2021 to address a leak around the exhaust fan.  The roofer noted that 3 layers are present - this may result in added labor/disposal cost.  The roof is in serviceable condition for now (2021).  Plan on replacement in 10 years.&lt;br /&gt;
|-&lt;br /&gt;
|Sump Pump&lt;br /&gt;
|2021&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$300&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Surge Tank&lt;br /&gt;
|1967&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$36,800&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|As of 2021, the [[Pool_Systems_Introduction#Surge_Tank|surge tank]] is overdue for an overhaul.  The tank in its present state is &amp;quot;severely deteriorated&amp;quot;, leaking, and lacking essential functionality presumably removed via low-budget modifications.  The cost for a full overhaul is estimated at $36,800 and must be performed when the pool is empty.&lt;br /&gt;
|-&lt;br /&gt;
|Variable Frequency Drive (VFD) for Main Pump Motor&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|10&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|10&lt;br /&gt;
|&lt;br /&gt;
|$1,200&lt;br /&gt;
|&lt;br /&gt;
|$1,500&lt;br /&gt;
|The main pump motor VFD is a Yaskawa GA50U2042ABA and was installed in 2022.  The lifespan is an estimate - and is subject to many variables.  Exposure to chemical vapors (chlorine, acid) and excess heat will reduce the lifespan.  Efforts have been made to limit exposure to both.  NOTE: The VFD has been shown to reduce club energy use by about 20 % (savings of $200-$300 a month in 2022).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Snack Shack ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Air Conditioner (Heat Pump)&lt;br /&gt;
|2022&lt;br /&gt;
|None&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|12&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|The air conditioner (heat pump) is a single-zone, 18,000 BTU 230 V &amp;quot;mini-split&amp;quot; unit.  The indoor unit is LG p/n LSN180HEV2, and the outdoor unit is LG p/n LSU180HEV2.  Lifespan estimates place heat pumps at 10-15 years.  The replacement cost is not known.  NOTE: This unit was installed primarily to reduce the burden on the refrigeration units in the snack shack, which would often operate 24/7 during hot periods of the summer.&lt;br /&gt;
|-&lt;br /&gt;
|Drywall (Ceiling)&lt;br /&gt;
|2019&lt;br /&gt;
|None&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The snack shack ceiling was replaced in 2019 due to failure (collapse).  There is no anticipated need to replace again at this time (at least not within the 20 year planning period).&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan&lt;br /&gt;
|2020&lt;br /&gt;
|None&lt;br /&gt;
|15&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|13&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|The exhaust fan is a Broan L700.  Starting in 2022, its usefulness going forward will be greatly reduced due to the installation of the A/C unit.  &lt;br /&gt;
|-&lt;br /&gt;
|Fire Extinguisher&lt;br /&gt;
|2019&lt;br /&gt;
|2021&lt;br /&gt;
|12&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|9&lt;br /&gt;
|$60&lt;br /&gt;
|$140&lt;br /&gt;
|$80&lt;br /&gt;
|$190&lt;br /&gt;
|Six-year maintenance ($38 in 2021 dollars) is due in 2025 and 2031.  Replacement ($90 in 2021 dollars) is due in 2031.  Annual servicing ($6 in 2021 dollars) is required.  Prices adjusted for inflation.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Ice Cream)&lt;br /&gt;
|2012&lt;br /&gt;
|None&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|10&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|$1,200&lt;br /&gt;
|&lt;br /&gt;
|The &amp;quot;Blue Bunny Ice Cream&amp;quot; freezer is a model 46SLC-LH-MFB, built in 2012.  The replacement cost is estimated to be $900 (an Avantco DFC16-HCL in 2021 dollars, adjusted for inflation in 2032).  Past experience during a power outage suggests that these units are not particularly well insulated.  A better replacement may be desired when the 20 year estimated lifespan (2032) arrives.&lt;br /&gt;
|-&lt;br /&gt;
|Freezer (Upright)&lt;br /&gt;
|2014&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#C6EFCE|12&lt;br /&gt;
|&lt;br /&gt;
|TBD&lt;br /&gt;
|$4,100&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a Supera F1R-1, DOM: 30-Mar-2014.  Last checked out by a refrigeration contractor in 2021.  The Supera brand is not well known/respected and may not last within the typical 15-20 year lifespan cited for commercial kitchen refrigeration units.  Repair parts may not be available (Supera appears to be defunct).  The estimated replacement cost is based upon an equivalent True unit.&lt;br /&gt;
|-&lt;br /&gt;
|Garbage Disposal&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|The installation date of the garbage disposal is not known at this time.&lt;br /&gt;
|-&lt;br /&gt;
|Microwave #1&lt;br /&gt;
|2016&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|$500&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a Sunbeam SGB8901.  This is a residential unit, and is over-stressed by high duty cycle use.  The average residential microwave is said to last 7 years - the estimate has been reduced to 5 as an estimate per the part-time heavy use.  The estimated replacement cost is based upon the purchase of a commercial microwave, better suited for the purpose.&lt;br /&gt;
|-&lt;br /&gt;
|Microwave #2&lt;br /&gt;
|2017&lt;br /&gt;
|None&lt;br /&gt;
|5&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$400&lt;br /&gt;
|&lt;br /&gt;
|$500&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a Samsung MS11K3000AS.  This is a residential unit, and is over-stressed by high duty cycle use.  The average residential microwave is said to last 7 years - the estimate has been reduced to 5 as an estimate per the part-time heavy use.  The estimated replacement cost is based upon the purchase of a commercial microwave, better suited for the purpose.&lt;br /&gt;
|-&lt;br /&gt;
|Refrigerator&lt;br /&gt;
|1997&lt;br /&gt;
|2021&lt;br /&gt;
|20&lt;br /&gt;
|style=&amp;quot;background:#FFC7CE|None&lt;br /&gt;
|$500&lt;br /&gt;
|$500&lt;br /&gt;
|$4,600&lt;br /&gt;
|&lt;br /&gt;
|The existing model is a True T-23, DOM: 1-May-1997.  Last checked out by a refrigeration contractor in 2021.  Setting aside $500 in 1-5 years and $500 in 5-10 years for repairs, replacement with another a True unit in 10-15 (unit will be nearly 40 years old).  No known issues with the existing unit other than it is 24 years old (as of 2021), exceeding the expected lifespan.  That said - given the seasonal use, it may last longer.  A True unit is highly repairable (as long as the fundamentals such as the cabinet are sound).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Women&#039;s Restroom ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Item&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Life Cycle (Years)&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Estimated Future&amp;lt;br&amp;gt;Investment&lt;br /&gt;
!rowspan=&amp;quot;2&amp;quot;|Comment&lt;br /&gt;
|-&lt;br /&gt;
!Install&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Last&amp;lt;br&amp;gt;Rehab&amp;lt;br&amp;gt;Year&lt;br /&gt;
!Typical&amp;lt;br&amp;gt;Useful&lt;br /&gt;
!Estimated&amp;lt;br&amp;gt;Remaining&amp;lt;br&amp;gt;(2021)&lt;br /&gt;
!1-5&amp;lt;br&amp;gt;Years&lt;br /&gt;
!5-10&amp;lt;br&amp;gt;Years&lt;br /&gt;
!10-15&amp;lt;br&amp;gt;Years&lt;br /&gt;
!15-20&amp;lt;br&amp;gt;Years&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fans (Small)&lt;br /&gt;
|Unknown&lt;br /&gt;
|N/A&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|There are two small exhaust fans in the women&#039;s restroom.  The larger of the two (13&amp;quot; assumed) is missing, the smaller (9&amp;quot; assumed) is in place, but non-functional (motor seized).  Replacement is recommended as soon as the budget permits (cost to be determined).&lt;br /&gt;
|-&lt;br /&gt;
|Exhaust Fan (Large)&lt;br /&gt;
|Unknown&lt;br /&gt;
|Unknown&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|The exhaust fan in the women&#039;s restroom is in poor condition.  Replacement is recommended as soon as the budget permits (cost to be determined).&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Lights&amp;diff=1756</id>
		<title>Pool Lights</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Lights&amp;diff=1756"/>
		<updated>2024-03-06T15:28:55Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|type=warn|text=The information on this page is out of date and pending review; the pool lights have been replaced with LED fixtures.}}&lt;br /&gt;
&lt;br /&gt;
To facilitate nighttime swimming, the Fairway Farms Swim Club has 10 underwater lights that provide illumination for the entire pool.  All fixtures are connected to centralized junction boxes with specialized pool grounding blocks.  The junction boxes are located near the north and west ends of the pool.&lt;br /&gt;
&lt;br /&gt;
The original fixtures are American Products R-500 BC, rated for a 120V/130V R40 medium base 500 W bulb.  The original housings are American Products model CN-5 (or equivalent).  Conversion to LED may occur in the future (at which point the entire fixture should be replaced to minimize risk of water leaks).&lt;br /&gt;
&lt;br /&gt;
==Wiring Diagram==&lt;br /&gt;
&lt;br /&gt;
The pool lights, along with additional circuits providing power receptacles on/near the pool deck and tennis courts are shown in the diagram below.  The dashed lines indicate connections only - the actual route of the conduit beneath the ground is not known.&lt;br /&gt;
&lt;br /&gt;
The hot and neutral connections within junction boxes and in the breaker panel are marked with the same identifying letters as shown in this drawing.&lt;br /&gt;
&lt;br /&gt;
The receptacles on the pool deck (circuits A and D) share a 20 A circuit.  The receptacle near the tennis courts has a dedicated 20 A feed.  Due to the long run and use of #12 AWG wire, some voltage drop should be expected on this outlet is heavy loads are used.  Observe that GFCI protection is provided via the in-line units inside the pump house; receptacles themselves to not contain GFCI protection but are GFCI protected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;responsive-image&amp;quot;&amp;gt;[[File:FFSC Pump House Ext Wiring.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Electrical Safety==&lt;br /&gt;
&lt;br /&gt;
All pool lights are protected by in-line GFCI devices that cut power in the event of a current imbalance (indicating leakage).  As with all electrical systems near a pool, safety is critical.  These GFCIs must be regularly tested and inspected.  Exposure to moisture and corrosive chemicals (i.e. hydrochloric acid and chlorine) may reduce their service life.  Replace as needed.&lt;br /&gt;
&lt;br /&gt;
In a standard incandescent pool light fixture, a spring that rests against the light bulb is intended to cause an intentional short-circuit to the filament in the event of a bulb breakage.  This will trip a protective device upstream, preventing the possibility of direct contact of water to electricity.&lt;br /&gt;
&lt;br /&gt;
==Replacement of Bulbs==&lt;br /&gt;
&lt;br /&gt;
Contrary to popular belief, the pool does not need to be drained to replace a light bulb.  The fixture is held into the niche (that mounted into the concrete) by a single screw.  During installation, sufficient cord is contained/looped in the niche to allow the fixture to be brought up to the pool deck for service.&lt;br /&gt;
&lt;br /&gt;
Details of the replacement won&#039;t be covered here - there are plenty of descriptions and YouTube videos that indicate how this process is done.  However, it MUST be noted that replacement of the gasket is mandatory.  This minimizes the risk of leaks.  Even so, it seems quite likely that a leak will form even with gasket replacement on an old fixture (due to an inadequate seal per corrosion, etc).&lt;br /&gt;
&lt;br /&gt;
Always ensure that power is off prior to servicing a fixture.  Never operate incandescent bulbs for an extended period of time out of water; the fixture is designed only to be operated underwater (to prevent overheating).&lt;br /&gt;
&lt;br /&gt;
==Upgrades in 2020==&lt;br /&gt;
&lt;br /&gt;
There were several updates made to the pool lights in 2020.  Additional circuits were added to prevent prior overload conditions (per code, a 20 A circuit cannot support a defined load above 80 %, or 16 A).  All GFCIs and switches were replaced as the existing units had significant corrosion due to years of moisture and chemical exposure.  The drawing above is the result of significant wire tracing and labeling efforts made during this upgrade.&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Lights&amp;diff=1755</id>
		<title>Pool Lights</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Pool_Lights&amp;diff=1755"/>
		<updated>2024-03-06T15:28:19Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: /* Wiring Diagram */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To facilitate nighttime swimming, the Fairway Farms Swim Club has 10 underwater lights that provide illumination for the entire pool.  All fixtures are connected to centralized junction boxes with specialized pool grounding blocks.  The junction boxes are located near the north and west ends of the pool.&lt;br /&gt;
&lt;br /&gt;
The original fixtures are American Products R-500 BC, rated for a 120V/130V R40 medium base 500 W bulb.  The original housings are American Products model CN-5 (or equivalent).  Conversion to LED may occur in the future (at which point the entire fixture should be replaced to minimize risk of water leaks).&lt;br /&gt;
&lt;br /&gt;
==Wiring Diagram==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=warn|text=The information in this subject is out of date and pending review; the pool lights have been replaced with LED fixtures.}}&lt;br /&gt;
&lt;br /&gt;
The pool lights, along with additional circuits providing power receptacles on/near the pool deck and tennis courts are shown in the diagram below.  The dashed lines indicate connections only - the actual route of the conduit beneath the ground is not known.&lt;br /&gt;
&lt;br /&gt;
The hot and neutral connections within junction boxes and in the breaker panel are marked with the same identifying letters as shown in this drawing.&lt;br /&gt;
&lt;br /&gt;
The receptacles on the pool deck (circuits A and D) share a 20 A circuit.  The receptacle near the tennis courts has a dedicated 20 A feed.  Due to the long run and use of #12 AWG wire, some voltage drop should be expected on this outlet is heavy loads are used.  Observe that GFCI protection is provided via the in-line units inside the pump house; receptacles themselves to not contain GFCI protection but are GFCI protected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;responsive-image&amp;quot;&amp;gt;[[File:FFSC Pump House Ext Wiring.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Electrical Safety==&lt;br /&gt;
&lt;br /&gt;
All pool lights are protected by in-line GFCI devices that cut power in the event of a current imbalance (indicating leakage).  As with all electrical systems near a pool, safety is critical.  These GFCIs must be regularly tested and inspected.  Exposure to moisture and corrosive chemicals (i.e. hydrochloric acid and chlorine) may reduce their service life.  Replace as needed.&lt;br /&gt;
&lt;br /&gt;
In a standard incandescent pool light fixture, a spring that rests against the light bulb is intended to cause an intentional short-circuit to the filament in the event of a bulb breakage.  This will trip a protective device upstream, preventing the possibility of direct contact of water to electricity.&lt;br /&gt;
&lt;br /&gt;
==Replacement of Bulbs==&lt;br /&gt;
&lt;br /&gt;
Contrary to popular belief, the pool does not need to be drained to replace a light bulb.  The fixture is held into the niche (that mounted into the concrete) by a single screw.  During installation, sufficient cord is contained/looped in the niche to allow the fixture to be brought up to the pool deck for service.&lt;br /&gt;
&lt;br /&gt;
Details of the replacement won&#039;t be covered here - there are plenty of descriptions and YouTube videos that indicate how this process is done.  However, it MUST be noted that replacement of the gasket is mandatory.  This minimizes the risk of leaks.  Even so, it seems quite likely that a leak will form even with gasket replacement on an old fixture (due to an inadequate seal per corrosion, etc).&lt;br /&gt;
&lt;br /&gt;
Always ensure that power is off prior to servicing a fixture.  Never operate incandescent bulbs for an extended period of time out of water; the fixture is designed only to be operated underwater (to prevent overheating).&lt;br /&gt;
&lt;br /&gt;
==Upgrades in 2020==&lt;br /&gt;
&lt;br /&gt;
There were several updates made to the pool lights in 2020.  Additional circuits were added to prevent prior overload conditions (per code, a 20 A circuit cannot support a defined load above 80 %, or 16 A).  All GFCIs and switches were replaced as the existing units had significant corrosion due to years of moisture and chemical exposure.  The drawing above is the result of significant wire tracing and labeling efforts made during this upgrade.&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Chlorinator&amp;diff=1754</id>
		<title>Chlorinator</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Chlorinator&amp;diff=1754"/>
		<updated>2024-03-06T14:36:11Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: /* Accu-Tab System */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Pulsar System ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=Further details to follow.}}&lt;br /&gt;
&lt;br /&gt;
== Accu-Tab System ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=The information in this section is preserved for historical reference.}}&lt;br /&gt;
&lt;br /&gt;
Prior to 2024, a PowerBase Model 3150 chlorinator (that utilized the &amp;quot;Accu-Tab&amp;quot; system) was responsible for chlorination.  This system was removed prior to the 2024 swim season.&lt;br /&gt;
&lt;br /&gt;
=== Retrospective ===&lt;br /&gt;
&lt;br /&gt;
Upon installing the new chlorinator prior to the 2024 swim season, we learned that the prior system should never have been sourced from &amp;quot;Unfiltered Water&amp;quot;.  This was likely a carry-over from an earlier system that passively relied upon a pressure differential to feed chlorine into the system.  Many of our issues (that were addressed via the modifications described below) could have likely been avoided had the system been re-plumbed to tap into &amp;quot;Filtered Water&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The inline Y-strainer was regularly bypassed, as once it captured debris, flow was reduced to the point that the chlorinator was starved of incoming water.  This would often lead to malfunction as contamination would clog up the solenoid when large debris was present in the incoming water.&lt;br /&gt;
&lt;br /&gt;
=== Theory of Operation ===&lt;br /&gt;
&lt;br /&gt;
==== Process Flow ====&lt;br /&gt;
&lt;br /&gt;
Water flows to the chlorinator from a tap on the outlet side of the main pump, i.e., &amp;quot;Unfiltered Water&amp;quot;.  An inline strainer provides a limited amount of filtration (i.e., ASTM 30, 600 &amp;amp;micro;m), preventing harmful particulates from entering the chlorinator.  Evidence has shown that the chlorinator solenoid is subject to malfunction without sufficient inline filtering.&lt;br /&gt;
&lt;br /&gt;
A bypass valve, whose exact purpose is not presently well understood, allows some amount of water flow to return to the pool essentially bypassing all mechanical filtration and chemical treatment.  Further investigation of use of this valve is needed.&lt;br /&gt;
&lt;br /&gt;
From this point, there are two paths for water to flow:&lt;br /&gt;
&lt;br /&gt;
* Into the tablet (upper) tank when the solenoid is active.  The solenoid is actuated (along with the pump) when there is a demand for adding chlorine.  Water flow in the tablet tank dissolves chlorine tabs and adds highly chlorinated water into the solution tank (pumped out to the pool).&lt;br /&gt;
* Into the solution (lower) tank when the float valve is open.  The float valve provides make-up water to maintain the solution tank level during operation (ideally 50 to 75 percent full).&lt;br /&gt;
&lt;br /&gt;
Water is pumped from the solution tank to the pool via a check valve, preventing pressure on the pool return line from forcing water back into the solution tank.&lt;br /&gt;
&lt;br /&gt;
==== Programmable Logic Controller ====&lt;br /&gt;
&lt;br /&gt;
[[File:Chlorinator PLC.jpg|thumbnail|The chlorinator electrical controls, with a custom PLC modification.]]&lt;br /&gt;
&lt;br /&gt;
In June 2021, a programmable logic controller (PLC) was added to the chlorinator power cabinet to mitigate air lock (loss of prime) conditions.  The PLC implementation was done solely in-house.&lt;br /&gt;
&lt;br /&gt;
A call for chlorination provides power to the PLC.  When the PLC is powered up, it automatically engages the pump and solenoid (per the high-level cut-off/float switch) by default.  If the float switch fails to engage after 10 seconds (indicating a drop in solution tank water level), the chlorinator pump motor is stopped for 10 seconds.  During this period, air bleeds from the pump.  After the 10 second period has elapsed, the pump is restarted.  Testing has shown this to be a highly effective method for restoring pump functionality.&lt;br /&gt;
&lt;br /&gt;
Subsequent checks of switch function occur every 60 seconds (rather than 10 to prevent frequent cycling).&lt;br /&gt;
&lt;br /&gt;
It should be noted that the float switch always controls the solenoid (via the PLC).  If the water level is high, the solenoid is disabled to prevent overflow of the solution tank.  Lacking a low-level switch, there is no means to prevent the pump from running dry.  Outside controls (such as verification of bypass line flow in the chemical controller) are used to ensure sufficient water is supplied to the chlorinator to prevent this from happening.&lt;br /&gt;
&lt;br /&gt;
=== Maintenance ===&lt;br /&gt;
&lt;br /&gt;
At some point, flow into the chlorinator is restricted by scale build-up on the sieve plate in the solid tablet tank.  This may result in prolonged operation upon a call for chlorine, as the water flow rate through the tabs is reduced.  When this occurs, cleaning is necessary.  It is assumed that cleaning should be performed at least once per season.&lt;br /&gt;
&lt;br /&gt;
To clean the tank, the following procedure is recommended (based on the manufacturer&#039;s procedure):&lt;br /&gt;
&lt;br /&gt;
# Open all doors in the pump house.  Proper ventilation is a must.&lt;br /&gt;
# Remove all solid tabs from the tank.&lt;br /&gt;
# Remove chlorine from the tank as much as possible by flushing it out with (pool) water.  This may be done by engaging the chlorinator manually via the Chemtrol unit.  A hose may be used to help loosen the scale.&lt;br /&gt;
# Once the excess water has drained (if a hose was used), stop the chlorinator pump.&lt;br /&gt;
# Remove the chlorinator from the loop by closing the isolation valves (near the boiler).&lt;br /&gt;
# Open the bypass valve.&lt;br /&gt;
# Carefully mix a diluted acid solution and pour it into the tank.  The manufacturer recommends 1 qt of muriatic acid to 2 gallons of water (remember to add acid to the water, not the other way around).  Extreme care must be taken to remove the chlorine prior (to prevent the generation of toxic chlorine gas).  Appropriate PPE must be worn.  The acid will produce carbon dioxide as it reacts with the scale.  Some chlorine gas may be produced - hence the absolute need for ventilation and PPE.&lt;br /&gt;
# Allow soaking for 30 minutes.&lt;br /&gt;
# Operate the chlorinator for 10 minutes.&lt;br /&gt;
# Open the isolation valves to begin flushing out acid.&lt;br /&gt;
# Use of a hose (again) may be required to fully wash out the acid.&lt;br /&gt;
# Return the chlorinator to automatic (or off) mode and re-fill with chlorine tabs.&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
==== Overflow ====&lt;br /&gt;
&lt;br /&gt;
Overflow in the reservoir (mixing basin) is likely due to the failure of one of two valves:&lt;br /&gt;
&lt;br /&gt;
* A PurAqua PASV150B solenoid valve controls water fill via the solid tablet tank.  This valve is electrically actuated by a small float switch.  Verify that the solenoid opens/closes (listen for an audible click) when the float switch is operated.  The valve&#039;s purpose is to stop water flow to the solid tablet tank (and ultimately the reservoir) when the water level has reached the upper threshold.  The build-up of contamination on the rubber diaphragm or debris in the housing may prevent the valve from fully closing, allowing water to flow uncontrolled.  To clean, remove the 1/2&amp;quot; bolts and separate the two metal parts carefully not to damage the rubber diaphragm.  Remove the diaphragm and clean surface contamination with fresh water.  Inspect for cracks, tears, or other signs of deterioration.  If all is in good working order, re-assemble (careful not to over-tighten the bolts).  Verify that the strainer (before the chlorinator) is installed and functioning properly.&lt;br /&gt;
&lt;br /&gt;
* Make-up water into the mixing basin is controlled by a mechanically-operated plunger valve, opened and closed by a float ball.  This valve is a 1-inch Kerick PT100SS.  This valve appears to make up the difference between outflow (via the chlorinator pump) and inflow that would otherwise only pass through the solid tablet tank.  The valve may, over time, become damaged or blocked by debris.  Inspect and clean as needed.  The valve can be purchased individually from various sources.  Alternatively, a rebuild kit (p/n 9500200) or the whole assembly (p/n 9501056) may be purchased from Aquatic Source or PurAqua Products.  Assuming the rod and float ball are in good condition, replacing only the valve (re-using the rod and float ball) is a good balance of cost and ease of repair.&lt;br /&gt;
&lt;br /&gt;
==== Pump Leakage ====&lt;br /&gt;
&lt;br /&gt;
The pump shaft seal may have failed.&lt;br /&gt;
&lt;br /&gt;
=== Drawings ===&lt;br /&gt;
&lt;br /&gt;
Chlorinator wiring, including the PLC, is shown in the drawing below.&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=This drawing does not include the additional modifications made to include a shut-off valve with additional level sense switches.}}&lt;br /&gt;
&lt;br /&gt;
[[File:FFSC-004 Pg 1 - Chlorinator.png|300px]]&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Chlorinator&amp;diff=1753</id>
		<title>Chlorinator</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Chlorinator&amp;diff=1753"/>
		<updated>2024-03-06T14:35:44Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: /* Historical Archive */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Pulsar System ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=Further details to follow.}}&lt;br /&gt;
&lt;br /&gt;
== Accu-Tab System ==&lt;br /&gt;
&lt;br /&gt;
Prior to 2024, a PowerBase Model 3150 chlorinator (that utilized the &amp;quot;Accu-Tab&amp;quot; system) was responsible for chlorination.  This system was removed prior to the 2024 swim season.&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=The information in this section is preserved for historical reference.}}&lt;br /&gt;
&lt;br /&gt;
=== Retrospective ===&lt;br /&gt;
&lt;br /&gt;
Upon installing the new chlorinator prior to the 2024 swim season, we learned that the prior system should never have been sourced from &amp;quot;Unfiltered Water&amp;quot;.  This was likely a carry-over from an earlier system that passively relied upon a pressure differential to feed chlorine into the system.  Many of our issues (that were addressed via the modifications described below) could have likely been avoided had the system been re-plumbed to tap into &amp;quot;Filtered Water&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The inline Y-strainer was regularly bypassed, as once it captured debris, flow was reduced to the point that the chlorinator was starved of incoming water.  This would often lead to malfunction as contamination would clog up the solenoid when large debris was present in the incoming water.&lt;br /&gt;
&lt;br /&gt;
=== Theory of Operation ===&lt;br /&gt;
&lt;br /&gt;
==== Process Flow ====&lt;br /&gt;
&lt;br /&gt;
Water flows to the chlorinator from a tap on the outlet side of the main pump, i.e., &amp;quot;Unfiltered Water&amp;quot;.  An inline strainer provides a limited amount of filtration (i.e., ASTM 30, 600 &amp;amp;micro;m), preventing harmful particulates from entering the chlorinator.  Evidence has shown that the chlorinator solenoid is subject to malfunction without sufficient inline filtering.&lt;br /&gt;
&lt;br /&gt;
A bypass valve, whose exact purpose is not presently well understood, allows some amount of water flow to return to the pool essentially bypassing all mechanical filtration and chemical treatment.  Further investigation of use of this valve is needed.&lt;br /&gt;
&lt;br /&gt;
From this point, there are two paths for water to flow:&lt;br /&gt;
&lt;br /&gt;
* Into the tablet (upper) tank when the solenoid is active.  The solenoid is actuated (along with the pump) when there is a demand for adding chlorine.  Water flow in the tablet tank dissolves chlorine tabs and adds highly chlorinated water into the solution tank (pumped out to the pool).&lt;br /&gt;
* Into the solution (lower) tank when the float valve is open.  The float valve provides make-up water to maintain the solution tank level during operation (ideally 50 to 75 percent full).&lt;br /&gt;
&lt;br /&gt;
Water is pumped from the solution tank to the pool via a check valve, preventing pressure on the pool return line from forcing water back into the solution tank.&lt;br /&gt;
&lt;br /&gt;
==== Programmable Logic Controller ====&lt;br /&gt;
&lt;br /&gt;
[[File:Chlorinator PLC.jpg|thumbnail|The chlorinator electrical controls, with a custom PLC modification.]]&lt;br /&gt;
&lt;br /&gt;
In June 2021, a programmable logic controller (PLC) was added to the chlorinator power cabinet to mitigate air lock (loss of prime) conditions.  The PLC implementation was done solely in-house.&lt;br /&gt;
&lt;br /&gt;
A call for chlorination provides power to the PLC.  When the PLC is powered up, it automatically engages the pump and solenoid (per the high-level cut-off/float switch) by default.  If the float switch fails to engage after 10 seconds (indicating a drop in solution tank water level), the chlorinator pump motor is stopped for 10 seconds.  During this period, air bleeds from the pump.  After the 10 second period has elapsed, the pump is restarted.  Testing has shown this to be a highly effective method for restoring pump functionality.&lt;br /&gt;
&lt;br /&gt;
Subsequent checks of switch function occur every 60 seconds (rather than 10 to prevent frequent cycling).&lt;br /&gt;
&lt;br /&gt;
It should be noted that the float switch always controls the solenoid (via the PLC).  If the water level is high, the solenoid is disabled to prevent overflow of the solution tank.  Lacking a low-level switch, there is no means to prevent the pump from running dry.  Outside controls (such as verification of bypass line flow in the chemical controller) are used to ensure sufficient water is supplied to the chlorinator to prevent this from happening.&lt;br /&gt;
&lt;br /&gt;
=== Maintenance ===&lt;br /&gt;
&lt;br /&gt;
At some point, flow into the chlorinator is restricted by scale build-up on the sieve plate in the solid tablet tank.  This may result in prolonged operation upon a call for chlorine, as the water flow rate through the tabs is reduced.  When this occurs, cleaning is necessary.  It is assumed that cleaning should be performed at least once per season.&lt;br /&gt;
&lt;br /&gt;
To clean the tank, the following procedure is recommended (based on the manufacturer&#039;s procedure):&lt;br /&gt;
&lt;br /&gt;
# Open all doors in the pump house.  Proper ventilation is a must.&lt;br /&gt;
# Remove all solid tabs from the tank.&lt;br /&gt;
# Remove chlorine from the tank as much as possible by flushing it out with (pool) water.  This may be done by engaging the chlorinator manually via the Chemtrol unit.  A hose may be used to help loosen the scale.&lt;br /&gt;
# Once the excess water has drained (if a hose was used), stop the chlorinator pump.&lt;br /&gt;
# Remove the chlorinator from the loop by closing the isolation valves (near the boiler).&lt;br /&gt;
# Open the bypass valve.&lt;br /&gt;
# Carefully mix a diluted acid solution and pour it into the tank.  The manufacturer recommends 1 qt of muriatic acid to 2 gallons of water (remember to add acid to the water, not the other way around).  Extreme care must be taken to remove the chlorine prior (to prevent the generation of toxic chlorine gas).  Appropriate PPE must be worn.  The acid will produce carbon dioxide as it reacts with the scale.  Some chlorine gas may be produced - hence the absolute need for ventilation and PPE.&lt;br /&gt;
# Allow soaking for 30 minutes.&lt;br /&gt;
# Operate the chlorinator for 10 minutes.&lt;br /&gt;
# Open the isolation valves to begin flushing out acid.&lt;br /&gt;
# Use of a hose (again) may be required to fully wash out the acid.&lt;br /&gt;
# Return the chlorinator to automatic (or off) mode and re-fill with chlorine tabs.&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
==== Overflow ====&lt;br /&gt;
&lt;br /&gt;
Overflow in the reservoir (mixing basin) is likely due to the failure of one of two valves:&lt;br /&gt;
&lt;br /&gt;
* A PurAqua PASV150B solenoid valve controls water fill via the solid tablet tank.  This valve is electrically actuated by a small float switch.  Verify that the solenoid opens/closes (listen for an audible click) when the float switch is operated.  The valve&#039;s purpose is to stop water flow to the solid tablet tank (and ultimately the reservoir) when the water level has reached the upper threshold.  The build-up of contamination on the rubber diaphragm or debris in the housing may prevent the valve from fully closing, allowing water to flow uncontrolled.  To clean, remove the 1/2&amp;quot; bolts and separate the two metal parts carefully not to damage the rubber diaphragm.  Remove the diaphragm and clean surface contamination with fresh water.  Inspect for cracks, tears, or other signs of deterioration.  If all is in good working order, re-assemble (careful not to over-tighten the bolts).  Verify that the strainer (before the chlorinator) is installed and functioning properly.&lt;br /&gt;
&lt;br /&gt;
* Make-up water into the mixing basin is controlled by a mechanically-operated plunger valve, opened and closed by a float ball.  This valve is a 1-inch Kerick PT100SS.  This valve appears to make up the difference between outflow (via the chlorinator pump) and inflow that would otherwise only pass through the solid tablet tank.  The valve may, over time, become damaged or blocked by debris.  Inspect and clean as needed.  The valve can be purchased individually from various sources.  Alternatively, a rebuild kit (p/n 9500200) or the whole assembly (p/n 9501056) may be purchased from Aquatic Source or PurAqua Products.  Assuming the rod and float ball are in good condition, replacing only the valve (re-using the rod and float ball) is a good balance of cost and ease of repair.&lt;br /&gt;
&lt;br /&gt;
==== Pump Leakage ====&lt;br /&gt;
&lt;br /&gt;
The pump shaft seal may have failed.&lt;br /&gt;
&lt;br /&gt;
=== Drawings ===&lt;br /&gt;
&lt;br /&gt;
Chlorinator wiring, including the PLC, is shown in the drawing below.&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=This drawing does not include the additional modifications made to include a shut-off valve with additional level sense switches.}}&lt;br /&gt;
&lt;br /&gt;
[[File:FFSC-004 Pg 1 - Chlorinator.png|300px]]&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Chlorinator&amp;diff=1752</id>
		<title>Chlorinator</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Chlorinator&amp;diff=1752"/>
		<updated>2024-03-06T14:29:18Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: /* Drawings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Pulsar System ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=Further details to follow.}}&lt;br /&gt;
&lt;br /&gt;
== Historical Archive ==&lt;br /&gt;
&lt;br /&gt;
Prior to 2024, a PowerBase Model 3150 chlorinator (that utilized the &amp;quot;Accu-Tab&amp;quot; system) was responsible for chlorination.  This system was removed prior to the 2024 swim season.&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=The information in this section is preserved for historical reference.}}&lt;br /&gt;
&lt;br /&gt;
=== Retrospective ===&lt;br /&gt;
&lt;br /&gt;
Upon installing the new chlorinator prior to the 2024 swim season, we learned that the prior system should never have been sourced from &amp;quot;Unfiltered Water&amp;quot;.  This was likely a carry-over from an earlier system that passively relied upon a pressure differential to feed chlorine into the system.  Many of our issues (that were addressed via the modifications described below) could have likely been avoided had the system been re-plumbed to tap into &amp;quot;Filtered Water&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The inline Y-strainer was regularly bypassed, as once it captured debris, flow was reduced to the point that the chlorinator was starved of incoming water.  This would often lead to malfunction as contamination would clog up the solenoid when large debris was present in the incoming water.&lt;br /&gt;
&lt;br /&gt;
=== Theory of Operation ===&lt;br /&gt;
&lt;br /&gt;
==== Process Flow ====&lt;br /&gt;
&lt;br /&gt;
Water flows to the chlorinator from a tap on the outlet side of the main pump, i.e., &amp;quot;Unfiltered Water&amp;quot;.  An inline strainer provides a limited amount of filtration (i.e., ASTM 30, 600 &amp;amp;micro;m), preventing harmful particulates from entering the chlorinator.  Evidence has shown that the chlorinator solenoid is subject to malfunction without sufficient inline filtering.&lt;br /&gt;
&lt;br /&gt;
A bypass valve, whose exact purpose is not presently well understood, allows some amount of water flow to return to the pool essentially bypassing all mechanical filtration and chemical treatment.  Further investigation of use of this valve is needed.&lt;br /&gt;
&lt;br /&gt;
From this point, there are two paths for water to flow:&lt;br /&gt;
&lt;br /&gt;
* Into the tablet (upper) tank when the solenoid is active.  The solenoid is actuated (along with the pump) when there is a demand for adding chlorine.  Water flow in the tablet tank dissolves chlorine tabs and adds highly chlorinated water into the solution tank (pumped out to the pool).&lt;br /&gt;
* Into the solution (lower) tank when the float valve is open.  The float valve provides make-up water to maintain the solution tank level during operation (ideally 50 to 75 percent full).&lt;br /&gt;
&lt;br /&gt;
Water is pumped from the solution tank to the pool via a check valve, preventing pressure on the pool return line from forcing water back into the solution tank.&lt;br /&gt;
&lt;br /&gt;
==== Programmable Logic Controller ====&lt;br /&gt;
&lt;br /&gt;
[[File:Chlorinator PLC.jpg|thumbnail|The chlorinator electrical controls, with a custom PLC modification.]]&lt;br /&gt;
&lt;br /&gt;
In June 2021, a programmable logic controller (PLC) was added to the chlorinator power cabinet to mitigate air lock (loss of prime) conditions.  The PLC implementation was done solely in-house.&lt;br /&gt;
&lt;br /&gt;
A call for chlorination provides power to the PLC.  When the PLC is powered up, it automatically engages the pump and solenoid (per the high-level cut-off/float switch) by default.  If the float switch fails to engage after 10 seconds (indicating a drop in solution tank water level), the chlorinator pump motor is stopped for 10 seconds.  During this period, air bleeds from the pump.  After the 10 second period has elapsed, the pump is restarted.  Testing has shown this to be a highly effective method for restoring pump functionality.&lt;br /&gt;
&lt;br /&gt;
Subsequent checks of switch function occur every 60 seconds (rather than 10 to prevent frequent cycling).&lt;br /&gt;
&lt;br /&gt;
It should be noted that the float switch always controls the solenoid (via the PLC).  If the water level is high, the solenoid is disabled to prevent overflow of the solution tank.  Lacking a low-level switch, there is no means to prevent the pump from running dry.  Outside controls (such as verification of bypass line flow in the chemical controller) are used to ensure sufficient water is supplied to the chlorinator to prevent this from happening.&lt;br /&gt;
&lt;br /&gt;
=== Maintenance ===&lt;br /&gt;
&lt;br /&gt;
At some point, flow into the chlorinator is restricted by scale build-up on the sieve plate in the solid tablet tank.  This may result in prolonged operation upon a call for chlorine, as the water flow rate through the tabs is reduced.  When this occurs, cleaning is necessary.  It is assumed that cleaning should be performed at least once per season.&lt;br /&gt;
&lt;br /&gt;
To clean the tank, the following procedure is recommended (based on the manufacturer&#039;s procedure):&lt;br /&gt;
&lt;br /&gt;
# Open all doors in the pump house.  Proper ventilation is a must.&lt;br /&gt;
# Remove all solid tabs from the tank.&lt;br /&gt;
# Remove chlorine from the tank as much as possible by flushing it out with (pool) water.  This may be done by engaging the chlorinator manually via the Chemtrol unit.  A hose may be used to help loosen the scale.&lt;br /&gt;
# Once the excess water has drained (if a hose was used), stop the chlorinator pump.&lt;br /&gt;
# Remove the chlorinator from the loop by closing the isolation valves (near the boiler).&lt;br /&gt;
# Open the bypass valve.&lt;br /&gt;
# Carefully mix a diluted acid solution and pour it into the tank.  The manufacturer recommends 1 qt of muriatic acid to 2 gallons of water (remember to add acid to the water, not the other way around).  Extreme care must be taken to remove the chlorine prior (to prevent the generation of toxic chlorine gas).  Appropriate PPE must be worn.  The acid will produce carbon dioxide as it reacts with the scale.  Some chlorine gas may be produced - hence the absolute need for ventilation and PPE.&lt;br /&gt;
# Allow soaking for 30 minutes.&lt;br /&gt;
# Operate the chlorinator for 10 minutes.&lt;br /&gt;
# Open the isolation valves to begin flushing out acid.&lt;br /&gt;
# Use of a hose (again) may be required to fully wash out the acid.&lt;br /&gt;
# Return the chlorinator to automatic (or off) mode and re-fill with chlorine tabs.&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
==== Overflow ====&lt;br /&gt;
&lt;br /&gt;
Overflow in the reservoir (mixing basin) is likely due to the failure of one of two valves:&lt;br /&gt;
&lt;br /&gt;
* A PurAqua PASV150B solenoid valve controls water fill via the solid tablet tank.  This valve is electrically actuated by a small float switch.  Verify that the solenoid opens/closes (listen for an audible click) when the float switch is operated.  The valve&#039;s purpose is to stop water flow to the solid tablet tank (and ultimately the reservoir) when the water level has reached the upper threshold.  The build-up of contamination on the rubber diaphragm or debris in the housing may prevent the valve from fully closing, allowing water to flow uncontrolled.  To clean, remove the 1/2&amp;quot; bolts and separate the two metal parts carefully not to damage the rubber diaphragm.  Remove the diaphragm and clean surface contamination with fresh water.  Inspect for cracks, tears, or other signs of deterioration.  If all is in good working order, re-assemble (careful not to over-tighten the bolts).  Verify that the strainer (before the chlorinator) is installed and functioning properly.&lt;br /&gt;
&lt;br /&gt;
* Make-up water into the mixing basin is controlled by a mechanically-operated plunger valve, opened and closed by a float ball.  This valve is a 1-inch Kerick PT100SS.  This valve appears to make up the difference between outflow (via the chlorinator pump) and inflow that would otherwise only pass through the solid tablet tank.  The valve may, over time, become damaged or blocked by debris.  Inspect and clean as needed.  The valve can be purchased individually from various sources.  Alternatively, a rebuild kit (p/n 9500200) or the whole assembly (p/n 9501056) may be purchased from Aquatic Source or PurAqua Products.  Assuming the rod and float ball are in good condition, replacing only the valve (re-using the rod and float ball) is a good balance of cost and ease of repair.&lt;br /&gt;
&lt;br /&gt;
==== Pump Leakage ====&lt;br /&gt;
&lt;br /&gt;
The pump shaft seal may have failed.&lt;br /&gt;
&lt;br /&gt;
=== Drawings ===&lt;br /&gt;
&lt;br /&gt;
Chlorinator wiring, including the PLC, is shown in the drawing below.&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=This drawing does not include the additional modifications made to include a shut-off valve with additional level sense switches.}}&lt;br /&gt;
&lt;br /&gt;
[[File:FFSC-004 Pg 1 - Chlorinator.png|300px]]&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Chlorinator&amp;diff=1751</id>
		<title>Chlorinator</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Chlorinator&amp;diff=1751"/>
		<updated>2024-03-06T14:29:06Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: /* Drawings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Pulsar System ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=Further details to follow.}}&lt;br /&gt;
&lt;br /&gt;
== Historical Archive ==&lt;br /&gt;
&lt;br /&gt;
Prior to 2024, a PowerBase Model 3150 chlorinator (that utilized the &amp;quot;Accu-Tab&amp;quot; system) was responsible for chlorination.  This system was removed prior to the 2024 swim season.&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=The information in this section is preserved for historical reference.}}&lt;br /&gt;
&lt;br /&gt;
=== Retrospective ===&lt;br /&gt;
&lt;br /&gt;
Upon installing the new chlorinator prior to the 2024 swim season, we learned that the prior system should never have been sourced from &amp;quot;Unfiltered Water&amp;quot;.  This was likely a carry-over from an earlier system that passively relied upon a pressure differential to feed chlorine into the system.  Many of our issues (that were addressed via the modifications described below) could have likely been avoided had the system been re-plumbed to tap into &amp;quot;Filtered Water&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The inline Y-strainer was regularly bypassed, as once it captured debris, flow was reduced to the point that the chlorinator was starved of incoming water.  This would often lead to malfunction as contamination would clog up the solenoid when large debris was present in the incoming water.&lt;br /&gt;
&lt;br /&gt;
=== Theory of Operation ===&lt;br /&gt;
&lt;br /&gt;
==== Process Flow ====&lt;br /&gt;
&lt;br /&gt;
Water flows to the chlorinator from a tap on the outlet side of the main pump, i.e., &amp;quot;Unfiltered Water&amp;quot;.  An inline strainer provides a limited amount of filtration (i.e., ASTM 30, 600 &amp;amp;micro;m), preventing harmful particulates from entering the chlorinator.  Evidence has shown that the chlorinator solenoid is subject to malfunction without sufficient inline filtering.&lt;br /&gt;
&lt;br /&gt;
A bypass valve, whose exact purpose is not presently well understood, allows some amount of water flow to return to the pool essentially bypassing all mechanical filtration and chemical treatment.  Further investigation of use of this valve is needed.&lt;br /&gt;
&lt;br /&gt;
From this point, there are two paths for water to flow:&lt;br /&gt;
&lt;br /&gt;
* Into the tablet (upper) tank when the solenoid is active.  The solenoid is actuated (along with the pump) when there is a demand for adding chlorine.  Water flow in the tablet tank dissolves chlorine tabs and adds highly chlorinated water into the solution tank (pumped out to the pool).&lt;br /&gt;
* Into the solution (lower) tank when the float valve is open.  The float valve provides make-up water to maintain the solution tank level during operation (ideally 50 to 75 percent full).&lt;br /&gt;
&lt;br /&gt;
Water is pumped from the solution tank to the pool via a check valve, preventing pressure on the pool return line from forcing water back into the solution tank.&lt;br /&gt;
&lt;br /&gt;
==== Programmable Logic Controller ====&lt;br /&gt;
&lt;br /&gt;
[[File:Chlorinator PLC.jpg|thumbnail|The chlorinator electrical controls, with a custom PLC modification.]]&lt;br /&gt;
&lt;br /&gt;
In June 2021, a programmable logic controller (PLC) was added to the chlorinator power cabinet to mitigate air lock (loss of prime) conditions.  The PLC implementation was done solely in-house.&lt;br /&gt;
&lt;br /&gt;
A call for chlorination provides power to the PLC.  When the PLC is powered up, it automatically engages the pump and solenoid (per the high-level cut-off/float switch) by default.  If the float switch fails to engage after 10 seconds (indicating a drop in solution tank water level), the chlorinator pump motor is stopped for 10 seconds.  During this period, air bleeds from the pump.  After the 10 second period has elapsed, the pump is restarted.  Testing has shown this to be a highly effective method for restoring pump functionality.&lt;br /&gt;
&lt;br /&gt;
Subsequent checks of switch function occur every 60 seconds (rather than 10 to prevent frequent cycling).&lt;br /&gt;
&lt;br /&gt;
It should be noted that the float switch always controls the solenoid (via the PLC).  If the water level is high, the solenoid is disabled to prevent overflow of the solution tank.  Lacking a low-level switch, there is no means to prevent the pump from running dry.  Outside controls (such as verification of bypass line flow in the chemical controller) are used to ensure sufficient water is supplied to the chlorinator to prevent this from happening.&lt;br /&gt;
&lt;br /&gt;
=== Maintenance ===&lt;br /&gt;
&lt;br /&gt;
At some point, flow into the chlorinator is restricted by scale build-up on the sieve plate in the solid tablet tank.  This may result in prolonged operation upon a call for chlorine, as the water flow rate through the tabs is reduced.  When this occurs, cleaning is necessary.  It is assumed that cleaning should be performed at least once per season.&lt;br /&gt;
&lt;br /&gt;
To clean the tank, the following procedure is recommended (based on the manufacturer&#039;s procedure):&lt;br /&gt;
&lt;br /&gt;
# Open all doors in the pump house.  Proper ventilation is a must.&lt;br /&gt;
# Remove all solid tabs from the tank.&lt;br /&gt;
# Remove chlorine from the tank as much as possible by flushing it out with (pool) water.  This may be done by engaging the chlorinator manually via the Chemtrol unit.  A hose may be used to help loosen the scale.&lt;br /&gt;
# Once the excess water has drained (if a hose was used), stop the chlorinator pump.&lt;br /&gt;
# Remove the chlorinator from the loop by closing the isolation valves (near the boiler).&lt;br /&gt;
# Open the bypass valve.&lt;br /&gt;
# Carefully mix a diluted acid solution and pour it into the tank.  The manufacturer recommends 1 qt of muriatic acid to 2 gallons of water (remember to add acid to the water, not the other way around).  Extreme care must be taken to remove the chlorine prior (to prevent the generation of toxic chlorine gas).  Appropriate PPE must be worn.  The acid will produce carbon dioxide as it reacts with the scale.  Some chlorine gas may be produced - hence the absolute need for ventilation and PPE.&lt;br /&gt;
# Allow soaking for 30 minutes.&lt;br /&gt;
# Operate the chlorinator for 10 minutes.&lt;br /&gt;
# Open the isolation valves to begin flushing out acid.&lt;br /&gt;
# Use of a hose (again) may be required to fully wash out the acid.&lt;br /&gt;
# Return the chlorinator to automatic (or off) mode and re-fill with chlorine tabs.&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
==== Overflow ====&lt;br /&gt;
&lt;br /&gt;
Overflow in the reservoir (mixing basin) is likely due to the failure of one of two valves:&lt;br /&gt;
&lt;br /&gt;
* A PurAqua PASV150B solenoid valve controls water fill via the solid tablet tank.  This valve is electrically actuated by a small float switch.  Verify that the solenoid opens/closes (listen for an audible click) when the float switch is operated.  The valve&#039;s purpose is to stop water flow to the solid tablet tank (and ultimately the reservoir) when the water level has reached the upper threshold.  The build-up of contamination on the rubber diaphragm or debris in the housing may prevent the valve from fully closing, allowing water to flow uncontrolled.  To clean, remove the 1/2&amp;quot; bolts and separate the two metal parts carefully not to damage the rubber diaphragm.  Remove the diaphragm and clean surface contamination with fresh water.  Inspect for cracks, tears, or other signs of deterioration.  If all is in good working order, re-assemble (careful not to over-tighten the bolts).  Verify that the strainer (before the chlorinator) is installed and functioning properly.&lt;br /&gt;
&lt;br /&gt;
* Make-up water into the mixing basin is controlled by a mechanically-operated plunger valve, opened and closed by a float ball.  This valve is a 1-inch Kerick PT100SS.  This valve appears to make up the difference between outflow (via the chlorinator pump) and inflow that would otherwise only pass through the solid tablet tank.  The valve may, over time, become damaged or blocked by debris.  Inspect and clean as needed.  The valve can be purchased individually from various sources.  Alternatively, a rebuild kit (p/n 9500200) or the whole assembly (p/n 9501056) may be purchased from Aquatic Source or PurAqua Products.  Assuming the rod and float ball are in good condition, replacing only the valve (re-using the rod and float ball) is a good balance of cost and ease of repair.&lt;br /&gt;
&lt;br /&gt;
==== Pump Leakage ====&lt;br /&gt;
&lt;br /&gt;
The pump shaft seal may have failed.&lt;br /&gt;
&lt;br /&gt;
=== Drawings ===&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=This drawing does not include the additional modifications made to include a shut-off valve with additional level sense switches.}}&lt;br /&gt;
&lt;br /&gt;
Chlorinator wiring, including the PLC, is shown in the drawing below.&lt;br /&gt;
&lt;br /&gt;
[[File:FFSC-004 Pg 1 - Chlorinator.png|300px]]&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Chlorinator&amp;diff=1750</id>
		<title>Chlorinator</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Chlorinator&amp;diff=1750"/>
		<updated>2024-03-06T14:27:14Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Pulsar System ==&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=Further details to follow.}}&lt;br /&gt;
&lt;br /&gt;
== Historical Archive ==&lt;br /&gt;
&lt;br /&gt;
Prior to 2024, a PowerBase Model 3150 chlorinator (that utilized the &amp;quot;Accu-Tab&amp;quot; system) was responsible for chlorination.  This system was removed prior to the 2024 swim season.&lt;br /&gt;
&lt;br /&gt;
{{Note|type=info|text=The information in this section is preserved for historical reference.}}&lt;br /&gt;
&lt;br /&gt;
=== Retrospective ===&lt;br /&gt;
&lt;br /&gt;
Upon installing the new chlorinator prior to the 2024 swim season, we learned that the prior system should never have been sourced from &amp;quot;Unfiltered Water&amp;quot;.  This was likely a carry-over from an earlier system that passively relied upon a pressure differential to feed chlorine into the system.  Many of our issues (that were addressed via the modifications described below) could have likely been avoided had the system been re-plumbed to tap into &amp;quot;Filtered Water&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The inline Y-strainer was regularly bypassed, as once it captured debris, flow was reduced to the point that the chlorinator was starved of incoming water.  This would often lead to malfunction as contamination would clog up the solenoid when large debris was present in the incoming water.&lt;br /&gt;
&lt;br /&gt;
=== Theory of Operation ===&lt;br /&gt;
&lt;br /&gt;
==== Process Flow ====&lt;br /&gt;
&lt;br /&gt;
Water flows to the chlorinator from a tap on the outlet side of the main pump, i.e., &amp;quot;Unfiltered Water&amp;quot;.  An inline strainer provides a limited amount of filtration (i.e., ASTM 30, 600 &amp;amp;micro;m), preventing harmful particulates from entering the chlorinator.  Evidence has shown that the chlorinator solenoid is subject to malfunction without sufficient inline filtering.&lt;br /&gt;
&lt;br /&gt;
A bypass valve, whose exact purpose is not presently well understood, allows some amount of water flow to return to the pool essentially bypassing all mechanical filtration and chemical treatment.  Further investigation of use of this valve is needed.&lt;br /&gt;
&lt;br /&gt;
From this point, there are two paths for water to flow:&lt;br /&gt;
&lt;br /&gt;
* Into the tablet (upper) tank when the solenoid is active.  The solenoid is actuated (along with the pump) when there is a demand for adding chlorine.  Water flow in the tablet tank dissolves chlorine tabs and adds highly chlorinated water into the solution tank (pumped out to the pool).&lt;br /&gt;
* Into the solution (lower) tank when the float valve is open.  The float valve provides make-up water to maintain the solution tank level during operation (ideally 50 to 75 percent full).&lt;br /&gt;
&lt;br /&gt;
Water is pumped from the solution tank to the pool via a check valve, preventing pressure on the pool return line from forcing water back into the solution tank.&lt;br /&gt;
&lt;br /&gt;
==== Programmable Logic Controller ====&lt;br /&gt;
&lt;br /&gt;
[[File:Chlorinator PLC.jpg|thumbnail|The chlorinator electrical controls, with a custom PLC modification.]]&lt;br /&gt;
&lt;br /&gt;
In June 2021, a programmable logic controller (PLC) was added to the chlorinator power cabinet to mitigate air lock (loss of prime) conditions.  The PLC implementation was done solely in-house.&lt;br /&gt;
&lt;br /&gt;
A call for chlorination provides power to the PLC.  When the PLC is powered up, it automatically engages the pump and solenoid (per the high-level cut-off/float switch) by default.  If the float switch fails to engage after 10 seconds (indicating a drop in solution tank water level), the chlorinator pump motor is stopped for 10 seconds.  During this period, air bleeds from the pump.  After the 10 second period has elapsed, the pump is restarted.  Testing has shown this to be a highly effective method for restoring pump functionality.&lt;br /&gt;
&lt;br /&gt;
Subsequent checks of switch function occur every 60 seconds (rather than 10 to prevent frequent cycling).&lt;br /&gt;
&lt;br /&gt;
It should be noted that the float switch always controls the solenoid (via the PLC).  If the water level is high, the solenoid is disabled to prevent overflow of the solution tank.  Lacking a low-level switch, there is no means to prevent the pump from running dry.  Outside controls (such as verification of bypass line flow in the chemical controller) are used to ensure sufficient water is supplied to the chlorinator to prevent this from happening.&lt;br /&gt;
&lt;br /&gt;
=== Maintenance ===&lt;br /&gt;
&lt;br /&gt;
At some point, flow into the chlorinator is restricted by scale build-up on the sieve plate in the solid tablet tank.  This may result in prolonged operation upon a call for chlorine, as the water flow rate through the tabs is reduced.  When this occurs, cleaning is necessary.  It is assumed that cleaning should be performed at least once per season.&lt;br /&gt;
&lt;br /&gt;
To clean the tank, the following procedure is recommended (based on the manufacturer&#039;s procedure):&lt;br /&gt;
&lt;br /&gt;
# Open all doors in the pump house.  Proper ventilation is a must.&lt;br /&gt;
# Remove all solid tabs from the tank.&lt;br /&gt;
# Remove chlorine from the tank as much as possible by flushing it out with (pool) water.  This may be done by engaging the chlorinator manually via the Chemtrol unit.  A hose may be used to help loosen the scale.&lt;br /&gt;
# Once the excess water has drained (if a hose was used), stop the chlorinator pump.&lt;br /&gt;
# Remove the chlorinator from the loop by closing the isolation valves (near the boiler).&lt;br /&gt;
# Open the bypass valve.&lt;br /&gt;
# Carefully mix a diluted acid solution and pour it into the tank.  The manufacturer recommends 1 qt of muriatic acid to 2 gallons of water (remember to add acid to the water, not the other way around).  Extreme care must be taken to remove the chlorine prior (to prevent the generation of toxic chlorine gas).  Appropriate PPE must be worn.  The acid will produce carbon dioxide as it reacts with the scale.  Some chlorine gas may be produced - hence the absolute need for ventilation and PPE.&lt;br /&gt;
# Allow soaking for 30 minutes.&lt;br /&gt;
# Operate the chlorinator for 10 minutes.&lt;br /&gt;
# Open the isolation valves to begin flushing out acid.&lt;br /&gt;
# Use of a hose (again) may be required to fully wash out the acid.&lt;br /&gt;
# Return the chlorinator to automatic (or off) mode and re-fill with chlorine tabs.&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
==== Overflow ====&lt;br /&gt;
&lt;br /&gt;
Overflow in the reservoir (mixing basin) is likely due to the failure of one of two valves:&lt;br /&gt;
&lt;br /&gt;
* A PurAqua PASV150B solenoid valve controls water fill via the solid tablet tank.  This valve is electrically actuated by a small float switch.  Verify that the solenoid opens/closes (listen for an audible click) when the float switch is operated.  The valve&#039;s purpose is to stop water flow to the solid tablet tank (and ultimately the reservoir) when the water level has reached the upper threshold.  The build-up of contamination on the rubber diaphragm or debris in the housing may prevent the valve from fully closing, allowing water to flow uncontrolled.  To clean, remove the 1/2&amp;quot; bolts and separate the two metal parts carefully not to damage the rubber diaphragm.  Remove the diaphragm and clean surface contamination with fresh water.  Inspect for cracks, tears, or other signs of deterioration.  If all is in good working order, re-assemble (careful not to over-tighten the bolts).  Verify that the strainer (before the chlorinator) is installed and functioning properly.&lt;br /&gt;
&lt;br /&gt;
* Make-up water into the mixing basin is controlled by a mechanically-operated plunger valve, opened and closed by a float ball.  This valve is a 1-inch Kerick PT100SS.  This valve appears to make up the difference between outflow (via the chlorinator pump) and inflow that would otherwise only pass through the solid tablet tank.  The valve may, over time, become damaged or blocked by debris.  Inspect and clean as needed.  The valve can be purchased individually from various sources.  Alternatively, a rebuild kit (p/n 9500200) or the whole assembly (p/n 9501056) may be purchased from Aquatic Source or PurAqua Products.  Assuming the rod and float ball are in good condition, replacing only the valve (re-using the rod and float ball) is a good balance of cost and ease of repair.&lt;br /&gt;
&lt;br /&gt;
==== Pump Leakage ====&lt;br /&gt;
&lt;br /&gt;
The pump shaft seal may have failed.&lt;br /&gt;
&lt;br /&gt;
=== Drawings ===&lt;br /&gt;
&lt;br /&gt;
Chlorinator wiring, including the PLC, is shown in the drawing below.&lt;br /&gt;
&lt;br /&gt;
[[File:FFSC-004 Pg 1 - Chlorinator.png|300px]]&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Bylaws&amp;diff=1749</id>
		<title>Bylaws</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Bylaws&amp;diff=1749"/>
		<updated>2024-01-25T16:26:02Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: /* Revision History */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;AMENDED AND RESTATED BY-LAWS OF THE FAIRWAY FARMS SWIM AND TENNIS CLUB AS OF AUGUST 15, 2023.&lt;br /&gt;
==ARTICLE I - NAME==&lt;br /&gt;
The name of this Corporation shall be the FAIRWAY FARMS SWIM AND TENNIS CLUB, hereinafter referred to as the &amp;quot;CLUB&amp;quot;.&lt;br /&gt;
==ARTICLE II - PURPOSE ==&lt;br /&gt;
The purpose for which the Club is formed is to operate a swimming pool and other recreational and social facilities, in the City of Livonia, State of Michigan, for the benefit of the Members, and to sell memberships in the Club to residents of Livonia and bordering communities. For purposes of this Article, the term &amp;quot;bordering communities&amp;quot; shall mean those cities and townships that touch any border of Livonia (including those cities within a township touching any border of Livonia). The exact number of Members in the Club who are not Livonia residents shall be determined from time to time by the Board of Directors.&lt;br /&gt;
However, in no case shall the total number of Members who are not Livonia residents ever exceed forty percent (40%) of the total membership at any one time. This limitation shall not, however, affect the status of any Member in the Club who is not a Livonia resident once that Member is admitted to the Club unless that Member moves out of a bordering community. In determining the exact number of Members in the Club who are not Livonia residents, the Board of Directors shall give full consideration to the number of Livonia residents waiting for membership in the Club and shall give those Livonia residents such preference over other applicants from bordering communities that the Board of Directors shall consider appropriate.&lt;br /&gt;
==ARTICLE III - GOVERNMENT==&lt;br /&gt;
===Section 1===&lt;br /&gt;
The Club shall be managed by a Board of Directors of at least four (4) and no more than thirteen (13) in number, the exact number of which shall be determined by the Board of Directors from time to time. In addition to this number, the Manager of the Pool shall be an Advisory Director and shall be entitled to all the rights and privileges of that position except, the Manager shall not be entitled to vote nor shall his presence at any meeting of the Board of Directors count towards establishing a required quorum.&lt;br /&gt;
===Section 2===&lt;br /&gt;
At each annual meeting of the Active Members of the Club, the [[Board Vice President|Vice President]] and alternatively, one-half of the other directors shall be elected each year from among the Active members. The President and [[Board Vice President|Vice President]] shall each serve a term of one year and all the other Directors shall serve for a term of two years (except as otherwise provided in Article VIII, Section 6) and until their successors have been chosen. The two Swim Team Coordinator positions shall be elected together and shall serve a term of two years in 2021 and 2022, 2023 and 2024, and 2025 and 2026. The next Swim Team Coordinator term shall be for three years in 2027, 2028 and 2029 and shall continue to alternate on two year then three-year terms. Any person elected to the Board of Directors for a particular office or committee shall not be entitled to serve a successive term for the same office or committee unless such person was elected to fill a vacancy in such office or committee or no one else in standing for election to such office or committee and the Board of Directors asks such person to serve again, in which case, such person can serve a successive term.&lt;br /&gt;
===Section 3===&lt;br /&gt;
Any Member of the Board of Directors who shall cease to hold Active Membership in the Club automatically shall cease to be a Member of the Board of Directors. Except as otherwise provided in Article VIII, Section 6, vacancies in the Board of Directors shall be appointed by the remaining Members of the Board, though less than a quorum, and each person so appointed shall be a Director until his successor is elected by the Members at the next annual meeting.&lt;br /&gt;
==ARTICLE IV - BOARD OF DIRECTORS==&lt;br /&gt;
===Section 1===&lt;br /&gt;
The Board of Directors shall consist of a President, a [[Board Vice President|Vice President]], a Secretary, a Treasurer and Vice Treasurer and such other representatives and chairpersons of committees, as the Board of Directors shall deem appropriate.&lt;br /&gt;
===Section 2===&lt;br /&gt;
The Board of Directors shall transact all Club business and shall have the authority to make and amend rules and regulations for the operation of Club and the Club&#039;s facilities. It may appoint and remove such clerks, agents; servants or employees as it may deem necessary and may fix their duties and compensation. The Board may constitute and appoint committees and define the powers and duties of the same.&lt;br /&gt;
===Section 3===&lt;br /&gt;
The Board of Directors shall designate the bank or banks in which the funds of the Club shall be deposited and determine the manner in which checks, drafts and other instruments for the payment of funds of the Club shall be executed.&lt;br /&gt;
===Section 4===&lt;br /&gt;
Any Member of the Board of Directors may be removed from office by the Members of the Club at a Special Meeting called in accordance with these By-Laws.&lt;br /&gt;
===Section 5===&lt;br /&gt;
The Board of Directors shall cause the books of the Club to be reviewed and prepared annually by Certified Public Accountants, selected by the Board, who shall neither be Members of the Board of Directors nor officers of the Club, and the report of the accountants shall be available to the Members upon request.&lt;br /&gt;
===Section 6===&lt;br /&gt;
The Board of Directors shall meet at least once a month during the months of January, February, March, April, May, June, July, August, September and October and at such other times, as it may deem appropriate. The Board shall be presided over by the President; in his absence the Board shall be presided over by the Vice-President. A majority of the Members of the Board present in person shall constitute a quorum. Voting members of the Board of Directors shall consist of the President, [[Board Vice President|Vice President]], Treasurer, Secretary, Membership and one representative from Building and Grounds, Social, Concessions and Swim Team. Members of such committees must reach a consensus or that committee will abstain from the vote. A majority vote of the Board Members present at a properly constituted meeting shall be required to carry a resolution or motion. Special meetings may be called by the President and shall be called by the Secretary upon the request of two (2) Members of the Board.&lt;br /&gt;
===Section 7===&lt;br /&gt;
In the event a question before the Board of Directors results in a tie vote, which cannot be resolved, the question may then be submitted to the membership for decision.&lt;br /&gt;
===Section 8===&lt;br /&gt;
The Board of Directors shall have the power to make such expenditures from available cash, as it considers appropriate. The Board of Directors shall not however, have the power to borrow any sum of money or mortgage any assets of the Club with or without collateral security, without first obtaining the approval of the Members of the Club as provided in these By-Laws.&lt;br /&gt;
===Section 9===&lt;br /&gt;
The Board of Directors shall have the power to enter into contracts for and on behalf of the Club and to designate one or more Members to sign any such contract.&lt;br /&gt;
===Section 10===&lt;br /&gt;
All current members of the Board of Directors shall have unlimited guest passes during their term.&lt;br /&gt;
===Section 11===&lt;br /&gt;
In consideration of service to the club, outgoing Board Members who have served a two year term and have attended 80% of the scheduled Board meetings during their term, shall receive complimentary membership dues&lt;br /&gt;
the year following their two year term. The past Board Member shall be responsible for the Capital Assessment Fee. The Swim Team Coordinators who are serving on a three year term shall receive complimentary membership dues following the first two years of their term provided they attend 80% of the meetings during the first two years. The Swim Team Coordinators shall also receive complimentary membership dues after serving as coordinators during the season which Fairway Farms hosts League Meet and provided they attend 80% of the meetings during that season. They shall also be responsible for the Capital Assessment Fee. No other compensation shall be received by any Board Members.&lt;br /&gt;
==ARTICLE V - OFFICERS==&lt;br /&gt;
===Section 1===&lt;br /&gt;
The President shall preside at all meetings of the Club and of the Board of Directors. He shall be the administrative officer of the Club. He shall appoint, subject to confirmation by the Board of Directors special committees. He shall be, ex-officio, a Member of all committees.&lt;br /&gt;
===Section 2===&lt;br /&gt;
The Vice-President, in the absence or temporary disability of the President, shall act in the President&#039;s stead. The [[Board Vice President|Vice President]] shall under the direction of the President, attend to the business and financial operations of the Club and shall be, ex-officio, a Member of all committees. After serving one year as [[Board Vice President|Vice President]], the [[Board Vice President|Vice President]] shall serve as President for the following year. If the [[Board Vice President|Vice President]] is then unable or unwilling to assume the office of President, a President shall be elected by the Members of the Club in the manner prescribed by the By-Laws.&lt;br /&gt;
===Section 3===&lt;br /&gt;
The Secretary or designate, shall send out the notices of the meetings of the Club and of the Board of Directors; keep the Minutes; mail any Club newsletter and the dues notices; and attend to the correspondence pertaining to such office. The Secretary shall perform such other duties pertaining to the office as may be asked by the Board of Directors.&lt;br /&gt;
===Section 4===&lt;br /&gt;
The Treasurer and Vice Treasurer shall attend to keeping the accounts of the Club, collecting its revenues, and paying its bills as approved by the Board of Directors or other agency authorized by the Board to incur them. The Treasurer shall deposit funds of the Club received by the Treasurer, in the name of the Club in such depository as may be authorized by the Board. The Treasurer shall perform such other duties pertaining to his office as may be asked by the Board.&lt;br /&gt;
===Section 5===&lt;br /&gt;
In the event of the death, resignation or incapacity of any of the Club officers, the Board of Directors shall select a successor who shall serve out such unexpired term.&lt;br /&gt;
==ARTICLE VI - MEMBERSHIP==&lt;br /&gt;
===Section 1===&lt;br /&gt;
The Membership of the Club shall be of three (3) classes, Active, Empty Nester, and Associate. Active memberships shall be limited to a maximum of three hundred fifty-five (355). Empty Nester and Associate memberships shall be limited to a number determined by the Board of Directors from time to time in its discretion.&lt;br /&gt;
&lt;br /&gt;
===Section 2===&lt;br /&gt;
An Active Member shall consist of those persons, not to exceed two (2), holding a Certificate of Membership and their unmarried children residing in their home. Proof of residency for unmarried adult children may be requested by the Membership Chair. Certificate of Membership shall be issued to no more than two adult names living in the same household. The Certificate shall provide for a right of survivorship.&lt;br /&gt;
===Section 3===&lt;br /&gt;
Section 3a - &lt;br /&gt;
An Empty Nester Member shall consist of those persons, not to exceed two (2), holding a certificate of membership. To qualify as an Empty Nester Member, both persons must live in the same household, and have been an Active Member of Fairway Farms Swim Club for a minimum of 10 years. Empty Nester Members cannot have an Associate Membership added. Empty Nester Memberships can only be converted from existing Active Memberships that have been in good standing with the club for a minimum of 10 years. Empty Nester bond conversion requests shall be approved by the Board of Directors on a case-by-case basis. Once an Active Membership has been converted to an Empty Nester Membership, an Active Membership will be made available to the next family on the waitlist. Should an Empty Nester Membership wish to convert back to an Active Membership, the member will notify the Membership Chairperson and their name will be placed at the end of the waitlist at the time notice is given.&lt;br /&gt;
&lt;br /&gt;
Section 3b - &lt;br /&gt;
An Associate Member is defined as a relative or other person associated with an Active Member (Mother, Father, Stepdaughter, Stepson, Nephew, Niece, Grandchild, etc), as approved by the Board of Directors in its sole and unfettered discretion. The terms and conditions of any Associate membership (including the amount of dues and fees payable for such membership and the term of such membership) shall be determined by the Board of Directors. An Associate membership may not be sold, assigned or transferred.&lt;br /&gt;
&lt;br /&gt;
===Section 4===&lt;br /&gt;
Any Member of any class may, for cause and after having been given an opportunity for a hearing, be suspended or have their membership bond revoked. A suspension shall not be for a period exceeding three months and during a suspension there shall be no refund of club dues. A revocation shall be immediately effective and the membership shall be sold in accordance with these By-Laws after which the bond and any dues to be refunded under Article VII(e)(f) shall be paid to the Member. A suspension or revocation shall require a two-thirds (2/3) vote of the Members of the Board of Directors present at any meeting thereof. Cause of suspension shall, in general, consist of violation of these By-Laws or of the rules or regulations of the club, or seriously objectionable or offensive conduct. Revocation of a Membership shall be for repeated offenders or for extraordinarily objectionable and offensive conduct.&lt;br /&gt;
===Section 5===&lt;br /&gt;
The Board of Directors has the power to suspend Club privileges for the violation of Club rules and regulations. A report of Club violations containing reasons therefore, shall be submitted to the President within 24 hours. The Board of Directors may delegate to the Manager or Assistant Manager of the Club the power to suspend Club privileges of Members under 18 years of age provided such suspension does not exceed seven (7) days. Suspension for more than one day will require notification of the President, Vice-President or other Board Member.&lt;br /&gt;
===Section 6===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;All Members of the Club shall be accorded the facilities of the Club subject to its rules and regulations.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Board of Directors shall by rule, fix the terms and conditions upon which guests of Members may use the facilities of the Club.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Any property of the Club broken or damaged by a Member of any class, or his guest, shall be promptly paid for by the responsible Member. No person shall take any article belonging to the Club without written permission of a person designated by the Club.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Club assumes no responsibility and Members or their guests can have no claim against the Club, for property of Members of any class, or any guest, which may be brought into or left in&amp;quot; the Club buildings, or on the grounds.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==ARTICLE VII - DUES AND FEES AND MEMBERSHIP CERTIFICATES==&lt;br /&gt;
===Section 1===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The annual dues of Fairway Farms are $585. These dues, along with the capital assessment fee as described in Article VII, Section 1(g) are due by March 15 of each year. A member may also pay dues in monthly installments of $200.00 each, with the first installment being due on March 1. The member who wishes to pay in monthly installments shall submit three checks payable to Fairway Farms, dated March 1, April 1 and May 1, and submit all three checks prior to March 1. The club will hold these three checks and present them to the bank for payment after the check dates. The member may either submit a fourth check dated March 15 for the capital assessment, or may add the capital assessment to the first check dated March 1. No installment payments will be accepted without the capital assessment check. Under either option, the envelope must be postmarked by the due date in order to avoid late fees.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;At the beginning of each year the Board of Directors shall establish dues and fees for each class of membership for the ensuing year. However, without the approval of the membership, the Board of Directors may not increase the dues and fees for any year by more than 10% from the immediately preceding year and in any case by more than 25% in the aggregate in any 5 year period.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dues and fees shall be sufficient to provide for the necessary operating expenses of the Club and the proper maintenance and improvement of its property, and such dues and fees shall be payable by such date as the Board of Directors shall determine (the &amp;quot;Due Date&amp;quot;). Any member who does not submit payment as described in section 1(a) or other indebtedness shall be subject to a 15% penalty of such delinquent amount and the same shall become immediately due and payable. Until such time as all such fees, dues, indebtedness, and penalties are “paid in full,” the Member shall be denied use of all Club facilities for that year’s season. Under no circumstances shall a member that is not “paid in full” be admitted to the club or participate in club activities.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Any special assessment proposed by the Board of Directors for any purpose shall require the vote of the Active Members at an Annual or Special Meeting called for that purpose.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;No dues or fees or any part thereof shall be refunded in the event pool operations are required to be suspended for any period. In the event of a sale or transfer of membership subsequent to the due date of any year, that year’s dues and fees will be refunded on the basis of the proportion of dues and fees that the new member must pay to the Club pursuant to Article VII(1)(f).&lt;br /&gt;
&amp;lt;li&amp;gt;Any person acquiring membership after the due date of any year shall pay Dues and Fees for that year on the following basis:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Due Date through June 15 = 100% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;June 16 through June 30 = 80% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;July 1 through July 15 = 60% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;July 16 through July 31= 40% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;August 1 through August 15 20% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;August 16 through close of Club for the season - no Dues or Fees required.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Provided that the total amount of Dues and Fees paid by the former Member and the new Member shall not exceed the total amount of Dues and Fees payable to the Club for the year for each membership.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;A Capital Improvement Fee of one hundred fifty dollars ($150) is to be paid by each member in cash or other conditions as established from time to time by the Board of Directors as pursuant to the vote of the members at the General Membership meeting held in 2020 and continuing on a yearly basis until amended as outlined in this Article. The Capital Improvement Fee will be used toward pool renovations and other improvements or repairs necessary to function as voted by the Board of Directors.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;A Capital Recovery Improvement Fee of one hundred dollars ($100) beginning fiscal year 2022 (which begins December 1, 2021) and beyond is to be paid by each new Member Bond in cash or other conditions as established from time to time by the Board of Directors.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Section 2===&lt;br /&gt;
Candidates for Active membership in the Club may be required to pay a nonrefundable application fee upon making application for membership. Moreover all applicants for Active and Associate Membership in the Club shall be required to pay a non-refundable initiation fee upon being granted membership. Notwithstanding the provisions of Article VII Section I (a) to the contrary, the amount of the application fee, if any, and the amount of the initiation fee shall be determined by the Board of Directors from time to time provided however, the amount of the initiation fee shall not exceed $50.00.&lt;br /&gt;
===Section 3===&lt;br /&gt;
As a condition to Active Membership, a Certificate of Membership shall be purchased. All such Certificates shall be sold for the sum of $650.00 cash. Initiation fees, dues and other fees shall be in addition to the cost of the Certificate of Membership.&lt;br /&gt;
===Section 4===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If an Active Member desires to sell, assign, transfer or in any manner, dispose of a Certificate of Membership, such Member must first offer to sell the Certificate to the Club in writing. The Club shall then have thirty (30) days within which to accept the offer. Such Member may withdraw said offer at any time before the Club accepts the offer by providing the Club with written notice thereof. If the Club accepts the offer, it shall provide notice thereof to such Member and Within 30 days of such notice, the Club shall tender the agreed upon sum to such Member whereupon; the Certificate of Membership shall be surrendered to the Club.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the Club fails to accept any such offer to sell within thirty (30) days of receipt of such offer or the Club, having duly accepted the offer, fails to tender the repurchase price within thirty (30) days after notifying such Member of its acceptance, then in either such event, the restrictions on the sale of that particular Certificate of Membership shall terminate and the holder of the Certificate shall be free to sell or transfer the Certificate upon the open market to any other person who is eligible for Active membership Linder these By-Laws and who shall pay the required initiation fee and dues.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the Active Member proposes to sell or lease such Member&#039;s residence, and desires the purchaser or lessee to have the first opportunity to acquire such Member&#039;s Certificate of Membership, then in that event, such Member&#039;s offer to sell the Certificate to the Club shall include a statement to this effect along with the name and address of the person purchasing or leasing the residence, and in such event, if the Club repurchases the Certificate of Membership, it shall offer such membership to the person purchasing or leasing such residence, for the sum of $650.00. Such person shall then have thirty (30) days to accept such offer. If such person accepts the offer, such person shall deliver written notice thereof to the Club and within 10 days of such notice, tender the sum of $650.00 to the Club and the required initiation fees and dues. If such person fails to accept such offer and pay the required sums, the Club shall be free to sell such membership to any eligible applicant.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Board of Directors may limit the periods of time during the year Certificates of Membership may be sold, assigned, transferred or otherwise disposed of. Moreover, in lieu of the Club purchasing any Certificate of Membership under this Article VII, the Board of Directors may require such Certificate be sold by the holder thereof directly to an applicant for membership designated by the Club. In such an event, such applicant shall pay such holder the sum of $650.00 whereupon, the holder shall surrender such Certificate to the Club and such applicant shall pay the required initiation fee and dues and other fees.&lt;br /&gt;
&amp;lt;li&amp;gt;If for any reason, a Certificate of Membership is not or cannot be tendered by any Member upon the sale, assignment, transfer, or other disposition thereof, the Club shall cancel such Certificate on it books and records and issue a replacement Certificate in which case, the date of such sale, assignment, transfer, or other disposition shall be deemed to be the date upon which the purchase price therefore is made available to the seller or transferor thereof.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 5===&lt;br /&gt;
All membership applications and transfers shall be subject to the approval of the Board of Directors or one of its Members designated by the Board for that purpose.&lt;br /&gt;
===Section 6===&lt;br /&gt;
Membership Certificates shall be transferable only on the books of the Club. All Certificates transferred in accordance with these By-Laws shall be tendered to the Secretary or any other designated person for cancellation and reissuance in the name of the transferee. For purposes of establishing an effective date, the transfer is deemed to take effect as of the date the Certificate is delivered to the Membership Chairperson or such other person.&lt;br /&gt;
===Section 7===&lt;br /&gt;
Upon dissolution of the Club, the assets of the Club shall be applied and distributed as:&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First, all liabilities and obligations of the Club shall be paid and discharged or adequate provision shall be made therefore.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Then, the remaining assets of the Club shall be liquidated and the proceeds thereof shall be distributed to the Active Members pro ratably. The Active Members shall be entitled to a pro rata distribution of the assets of the Club after payment of all debts and liquidation of all liabilities. Associate Members shall not share in any distribution and liquidation of assets.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 8===&lt;br /&gt;
The Club shall have a lien upon and charge against a Member’s Certificate of Membership for any and all unpaid fees, dues and other indebtedness owing to the Club by Member. The lien may be enforced by cancellation and sale of the Membership at such time as amounts remain unpaid as of May 1. In the event the Club is unable to obtain possession of the Certificate, it may be canceled upon the books of the Club, the membership may be sold, and a new Certificate issued to the purchaser thereof. In the event of the enforcement of a lien as herein provided, neither the signature of the holder nor delivery of the Certificate shall be required to perfect the transfer, and the Membership Chairperson of the Club is authorized as attorney of the holder of the Certificate, to make such transfer. In the event that the lien is satisfied by a cancellation and resale of the membership, the Club shall account to and pay over to the delinquent Member, the excess of the resale price over the indebtedness. Every Certificate of Membership issued is expressly subject to the provisions of this section.&lt;br /&gt;
===Section 9===&lt;br /&gt;
All fees and other charges mentioned herein are exclusive of all taxes imposed by State, Federal and other Government bodies and agencies.&lt;br /&gt;
===Section 10===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;In the event that a membership certificate is held jointly, and that relationship is terminated by divorce or legal separation, only one individual shall continue the membership and the Board of Directors will issue a new membership certificate in the name agreed to by the parties or as adjudged by a court of law upon receipt of a certified copy of the court order/judgment.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The individual not named on the new certificate shall be eligible for membership and shall immediately be placed at the front of the wait list, if one exists.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;In the event that a divorce or legal separation is final and no determination or agreement is made: the certificate may be terminated on the following March 1st and the certificate may be repurchased by the club. Each party shall be eligible to purchase a new membership and be placed at the front of the wait list, if one exists.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==ARTICLE VIII - MEMBERSHIP MEETINGS==&lt;br /&gt;
===Section 1===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Annual Meeting of the Club shall be held each calendar year on a date and at such place and time as the Board of Directors may determine.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Annual Meeting shall be for the purpose of electing Directors, presenting committee reports, and for the transaction of such other business as may be indicated in the notice.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 2===&lt;br /&gt;
Special Meetings of the Club may be called by the Board of Directors. Also, upon the written request of sixty (60) Members to the Secretary, stating the purpose therefore, a Special Meeting shall be called by the Secretary within thirty (30) days.&lt;br /&gt;
===Section 3===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Written notice of the Annual Meeting must be given to all Active Members not less than ten (10) days nor more than sixty (60) days prior to the date of the Meeting. Notice of the Annual Meeting shall indicate the number of Directors to be elected and the names of any Members known to the Board of Directors to be standing for election.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Written notice of any Special Meeting must be given to all Active Members not less than ten (10) days nor more than sixty (60) days prior to any Special Meeting. Notice of any Special Meeting shall state the purposes for which the Special Meeting is called, and no other business shall be transacted thereat.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 4===&lt;br /&gt;
Only Active Members shall be entitled to vote at meetings of the Club. Each Active membership shall be entitled to one vote. In cases where a Membership is in the name of more than one person, either, but not both, of such persons may vote. Voting may be in person, by proxy, by written ballot or by voice, but if by voice, ten (10) Members shall have the right to demand voting by roll call or in writing.&lt;br /&gt;
===Section 5===&lt;br /&gt;
Ten (10%) percent of the Active Members, present in person or by proxy at a meeting of the Club shall constitute a quorum. A majority vote of the Active Members present in person or by proxy at a constituted meeting shall be sufficient to carry a resolution or a motion.&lt;br /&gt;
===Section 6===&lt;br /&gt;
Candidates for election to the Board of Directors as a specific officer, representative or committee chairperson, shall stand for election as such and the candidate receiving a majority of the votes cast by Members entitled to vote thereon shall be so elected to such position. In the case of a tie, a second vote shall be taken. If a tie shall result from the second vote, a majority vote of the Board of Directors present in person at the meeting shall determine the winner and the first runner-up shall serve as an alternate in case the winner shall later resign or be removed during the term of office. Candidates for election to the Board of Directors at-large, shall all stand for election together. Directors for such at-large positions shall be elected by a plurality of the votes cast by Members entitled to vote thereon.&lt;br /&gt;
===Section 7===&lt;br /&gt;
A General Information Meeting may be held on a date and at such place and time as the board of Directors may determine. Written notice of a General Information Meeting must be given to all Active Members not less than ten (10) days nor more than sixty (60) days prior to any General Information Meeting. The purpose of the General Information Meeting may be to present the Budget for the Club for the ensuing year which the Board of Directors has approved and such other information as the Board may determine is appropriate for the general information of the membership. No quorum is required to constitute a General Information Meeting and no action may be taken thereat on a resolution, motion or any other matter.&lt;br /&gt;
===Section 8===&lt;br /&gt;
The Board of Directors may from time to time, adopt and prescribe reasonable procedures regarding the nomination and election of candidates to the Board of Directors, the submission of any matter to the vote of the membership, and the conducting of all Meetings of the Club. Roberts Rules of Order will prevail at all Meetings of the Club.&lt;br /&gt;
==ARTICLE IX - COMMITTEES==&lt;br /&gt;
===Section 1===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The standing committees shall be Buildings and Grounds, Social, Membership, Concessions and Swim Team.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The duties and powers assigned in these By-Laws to the standing committees shall be subject to the authority and modification of the Board of Directors. No Committee shall expend funds without prior appropriation by the Board of Directors.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 2===&lt;br /&gt;
The Buildings and Grounds Committee shall exercise supervision over the Pool/Buildings and Grounds; shall attend to the improvement and maintenance of the Pool/Buildings and Grounds and its operating equipment; shall have the authority thereover; and shall see that the rules and regulations of the Club relating to the Pool/ Buildings and Grounds are enforced.&lt;br /&gt;
===Section 3===&lt;br /&gt;
The Social Committee shall plan and supervise all parties and social functions for the Club.&lt;br /&gt;
===Section 4===&lt;br /&gt;
The Membership Committee shall exercise supervision over the inquiries, applications, approval, admittance and termination of all memberships in the Club; shall adopt and prescribe such procedures, as it deems appropriate for the orderly operation thereof; and shall collect all monies from new Members and remit the same to the Club.&lt;br /&gt;
===Section 5===&lt;br /&gt;
The Concessions Committee shall exercise supervision over the operation of the Concession area; shall have authority thereover; and shall procure the needed supplies and concessions.&lt;br /&gt;
===Section 6===&lt;br /&gt;
Such temporary committees as deemed necessary may be appointed by the Board of Directors and they shall terminate when the purpose of their formation has been fulfilled.&lt;br /&gt;
==ARTICLE X - INDEMNIFICATION: MISCELLANEOUS==&lt;br /&gt;
===Section 1===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Unless otherwise provided by law, the Club shall indemnify a person who was or is a party or is threatened to be made a party to a threatened, pending or completed action, suit, or proceeding, whether civil, criminal, administrative, or investigative and whether formal or informal, other than an action by or in the right of the Club, by reason of the fact that he or she is or was a director, officer, or employee of the Club, or is or was serving at the request of the Club as a director, officer, partner, trustee, employee, or agent of another foreign or domestic corporation, partnership, joint Venture, trust, or other enterprise, whether for profit or not, including attorneys&#039; fees, judgments, penalties, fines, and amounts paid in settlement actually and reasonably incurred by the person in connection with the action, suit or proceeding, if the person acted in good faith and in a manner the person reasonably believed to be in or not opposed to the best interests of the Club or its Members, and with respect to a criminal action or proceeding, if the person had no reasonable cause to believe his or her conduct was unlawful. The termination of any action, suit, or proceeding by judgment, order, settlement, conviction, or upon a plea of nolo contendere or its equivalent, does not, of itself, create a presumption that the person did not act in good faith and in a manner which he or she reasonably believed to be or not opposed to the best interests of the Club or its&lt;br /&gt;
Members, and with respect to a criminal action or proceeding, had reasonable cause to believe that his or her conduct was unlawful.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Unless otherwise provided by law, the Club shall indemnify any person who was or is a party to or is threatened to be made a party to a threatened, pending, or completed action or suit by or in the right of the Club to procure a judgment in its favor or by reason of the fact that he or she is or was a director, officer, or employee of the Club, or is or was serving at the request of the Club as a director, officer, partner, trustee, employee, or agent of another foreign or domestic corporation, partnership, joint venture, trust, or other enterprise, whether for profit or not, against expenses, including attorneys&#039; fees, and amounts paid in settlement actually and reasonably incurred by the person in connection with the action or suit, if the person acted in good faith and in a manner the person reasonably believed to be in or not opposed to the best interests of the Club or its Members. However, indemnification shall not be made for a claim, issue, or matter in which the person has been found liable to the Club unless and only to the&lt;br /&gt;
extent that the court in which the action or suit was brought has determined upon application that despite the adjudication of liability, but in view of all circumstances of the case, the person is fairly and reasonably entitled to indemnification for expenses which the court considers proper.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 2===&lt;br /&gt;
These By-Laws may be amended by a vote of the Active Members at any Meeting of the Club.&lt;br /&gt;
===Section 3===&lt;br /&gt;
Notwithstanding any provisions of these By-Laws to the contrary, no part of the net earnings of this club shall inure to the benefit of any member. An Active or Associate Member may be given consideration if he or she has proper background, training, thorough knowledge and applies for such position(s): (1) Fitness Instructor; (2) Diving Instructor; (3) Tennis Instructor; (4) Swim Coach, (5) Lifeguard or (6) Concession worker. Said position shall not be filled by a Board Member in his/her current term. Each position is considered “Contract” not “Ongoing”. Each position will be reconsidered on an annual basis.&lt;br /&gt;
&lt;br /&gt;
==Revision History==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Section&lt;br /&gt;
!Comment&lt;br /&gt;
|-&lt;br /&gt;
|January 2024&lt;br /&gt;
|Article VII, Section 1, g&lt;br /&gt;
|A delayed update to the bylaws to reflect the increased capital fee from $100 to $150 per an August 15th, 2023 vote by General Membership.&lt;br /&gt;
|-&lt;br /&gt;
|February 2023&lt;br /&gt;
|Article VII Section 1&lt;br /&gt;
|Increased annual dues from $550 to $585 (+6.3%) per a February 13th, 2023 board vote.&lt;br /&gt;
|-&lt;br /&gt;
|August 2022&lt;br /&gt;
|Article IV Section 1&lt;br /&gt;
|Added a Vice Treasurer position by vote of General Membership on August 16, 2022.&lt;br /&gt;
|-&lt;br /&gt;
|September 2022&lt;br /&gt;
|Article VII Section 1&lt;br /&gt;
|A delayed update to the bylaws to identify an increase in the annual dues from $525 to $550 (+4.8%) per a January 10th, 2022 board vote.&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=4|August 2020&lt;br /&gt;
|Article III Section 2&lt;br /&gt;
|Changed swim team coordinator terms (alignment for the lost 2020 season) per approval by the board and members at the 2020 annual meeting.&lt;br /&gt;
|-&lt;br /&gt;
|Article VI Section 1&lt;br /&gt;
|Increased the number of member bonds from 330 to 340 per approval by the board and members at the 2020 annual meeting.&lt;br /&gt;
|-&lt;br /&gt;
|Article VII Section 1, g&lt;br /&gt;
|Increased the capital fee from $75 to $100 per approval by the board and members at the 2020 annual meeting.&lt;br /&gt;
|-&lt;br /&gt;
|Article VII Section 1, h (added)&lt;br /&gt;
|Added the Capital Recovery fee of $100 per approval by the board and members at the 2020 annual meeting.&lt;br /&gt;
|-&lt;br /&gt;
|August 2020&lt;br /&gt;
|&lt;br /&gt;
|Document Transferred to Wiki&lt;br /&gt;
|-&lt;br /&gt;
|August 2019&lt;br /&gt;
|Article VI Section 2&amp;lt;br/&amp;gt;Article VII Section 10&lt;br /&gt;
|General Member Approval Vote&lt;br /&gt;
|-&lt;br /&gt;
|June 2018&lt;br /&gt;
|Article III, Section 2&amp;lt;br/&amp;gt;Article IV, Section 11&amp;lt;br/&amp;gt;Article VI, Section 2&amp;lt;br/&amp;gt;Article VII, Section 1(a), Section 1(e), Section 1(f), Section 8&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Feb 2017&lt;br /&gt;
|Article VII, Section 1(a)&lt;br /&gt;
|Amended Membership Dues fee per Board Member Vote&lt;br /&gt;
|-&lt;br /&gt;
|Sep 2016&lt;br /&gt;
|Article VI, Section 4&lt;br /&gt;
|Amended per Aug 2016 General Member Approval Vote&lt;br /&gt;
|-&lt;br /&gt;
|Feb 2016&lt;br /&gt;
|Article X, Section 3&lt;br /&gt;
|Amended per Aug 2015 General Member Approval Vote&lt;br /&gt;
|-&lt;br /&gt;
|Aug 2012&lt;br /&gt;
|&lt;br /&gt;
|Document Amended and Approved&lt;br /&gt;
|-&lt;br /&gt;
|Aug 2011&lt;br /&gt;
|&lt;br /&gt;
|Document Amended and Approved&lt;br /&gt;
|-&lt;br /&gt;
|Sep 2004&lt;br /&gt;
|&lt;br /&gt;
|Entire Document Scanned and Re-Formatted into Word&lt;br /&gt;
|-&lt;br /&gt;
|July 2000&lt;br /&gt;
|&lt;br /&gt;
|Entire Document Revised&lt;br /&gt;
|-&lt;br /&gt;
|Nov 6, 1991&lt;br /&gt;
|&lt;br /&gt;
|Entire Document Developed By-Laws Document&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Bylaws&amp;diff=1748</id>
		<title>Bylaws</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Bylaws&amp;diff=1748"/>
		<updated>2024-01-25T16:25:32Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;AMENDED AND RESTATED BY-LAWS OF THE FAIRWAY FARMS SWIM AND TENNIS CLUB AS OF AUGUST 15, 2023.&lt;br /&gt;
==ARTICLE I - NAME==&lt;br /&gt;
The name of this Corporation shall be the FAIRWAY FARMS SWIM AND TENNIS CLUB, hereinafter referred to as the &amp;quot;CLUB&amp;quot;.&lt;br /&gt;
==ARTICLE II - PURPOSE ==&lt;br /&gt;
The purpose for which the Club is formed is to operate a swimming pool and other recreational and social facilities, in the City of Livonia, State of Michigan, for the benefit of the Members, and to sell memberships in the Club to residents of Livonia and bordering communities. For purposes of this Article, the term &amp;quot;bordering communities&amp;quot; shall mean those cities and townships that touch any border of Livonia (including those cities within a township touching any border of Livonia). The exact number of Members in the Club who are not Livonia residents shall be determined from time to time by the Board of Directors.&lt;br /&gt;
However, in no case shall the total number of Members who are not Livonia residents ever exceed forty percent (40%) of the total membership at any one time. This limitation shall not, however, affect the status of any Member in the Club who is not a Livonia resident once that Member is admitted to the Club unless that Member moves out of a bordering community. In determining the exact number of Members in the Club who are not Livonia residents, the Board of Directors shall give full consideration to the number of Livonia residents waiting for membership in the Club and shall give those Livonia residents such preference over other applicants from bordering communities that the Board of Directors shall consider appropriate.&lt;br /&gt;
==ARTICLE III - GOVERNMENT==&lt;br /&gt;
===Section 1===&lt;br /&gt;
The Club shall be managed by a Board of Directors of at least four (4) and no more than thirteen (13) in number, the exact number of which shall be determined by the Board of Directors from time to time. In addition to this number, the Manager of the Pool shall be an Advisory Director and shall be entitled to all the rights and privileges of that position except, the Manager shall not be entitled to vote nor shall his presence at any meeting of the Board of Directors count towards establishing a required quorum.&lt;br /&gt;
===Section 2===&lt;br /&gt;
At each annual meeting of the Active Members of the Club, the [[Board Vice President|Vice President]] and alternatively, one-half of the other directors shall be elected each year from among the Active members. The President and [[Board Vice President|Vice President]] shall each serve a term of one year and all the other Directors shall serve for a term of two years (except as otherwise provided in Article VIII, Section 6) and until their successors have been chosen. The two Swim Team Coordinator positions shall be elected together and shall serve a term of two years in 2021 and 2022, 2023 and 2024, and 2025 and 2026. The next Swim Team Coordinator term shall be for three years in 2027, 2028 and 2029 and shall continue to alternate on two year then three-year terms. Any person elected to the Board of Directors for a particular office or committee shall not be entitled to serve a successive term for the same office or committee unless such person was elected to fill a vacancy in such office or committee or no one else in standing for election to such office or committee and the Board of Directors asks such person to serve again, in which case, such person can serve a successive term.&lt;br /&gt;
===Section 3===&lt;br /&gt;
Any Member of the Board of Directors who shall cease to hold Active Membership in the Club automatically shall cease to be a Member of the Board of Directors. Except as otherwise provided in Article VIII, Section 6, vacancies in the Board of Directors shall be appointed by the remaining Members of the Board, though less than a quorum, and each person so appointed shall be a Director until his successor is elected by the Members at the next annual meeting.&lt;br /&gt;
==ARTICLE IV - BOARD OF DIRECTORS==&lt;br /&gt;
===Section 1===&lt;br /&gt;
The Board of Directors shall consist of a President, a [[Board Vice President|Vice President]], a Secretary, a Treasurer and Vice Treasurer and such other representatives and chairpersons of committees, as the Board of Directors shall deem appropriate.&lt;br /&gt;
===Section 2===&lt;br /&gt;
The Board of Directors shall transact all Club business and shall have the authority to make and amend rules and regulations for the operation of Club and the Club&#039;s facilities. It may appoint and remove such clerks, agents; servants or employees as it may deem necessary and may fix their duties and compensation. The Board may constitute and appoint committees and define the powers and duties of the same.&lt;br /&gt;
===Section 3===&lt;br /&gt;
The Board of Directors shall designate the bank or banks in which the funds of the Club shall be deposited and determine the manner in which checks, drafts and other instruments for the payment of funds of the Club shall be executed.&lt;br /&gt;
===Section 4===&lt;br /&gt;
Any Member of the Board of Directors may be removed from office by the Members of the Club at a Special Meeting called in accordance with these By-Laws.&lt;br /&gt;
===Section 5===&lt;br /&gt;
The Board of Directors shall cause the books of the Club to be reviewed and prepared annually by Certified Public Accountants, selected by the Board, who shall neither be Members of the Board of Directors nor officers of the Club, and the report of the accountants shall be available to the Members upon request.&lt;br /&gt;
===Section 6===&lt;br /&gt;
The Board of Directors shall meet at least once a month during the months of January, February, March, April, May, June, July, August, September and October and at such other times, as it may deem appropriate. The Board shall be presided over by the President; in his absence the Board shall be presided over by the Vice-President. A majority of the Members of the Board present in person shall constitute a quorum. Voting members of the Board of Directors shall consist of the President, [[Board Vice President|Vice President]], Treasurer, Secretary, Membership and one representative from Building and Grounds, Social, Concessions and Swim Team. Members of such committees must reach a consensus or that committee will abstain from the vote. A majority vote of the Board Members present at a properly constituted meeting shall be required to carry a resolution or motion. Special meetings may be called by the President and shall be called by the Secretary upon the request of two (2) Members of the Board.&lt;br /&gt;
===Section 7===&lt;br /&gt;
In the event a question before the Board of Directors results in a tie vote, which cannot be resolved, the question may then be submitted to the membership for decision.&lt;br /&gt;
===Section 8===&lt;br /&gt;
The Board of Directors shall have the power to make such expenditures from available cash, as it considers appropriate. The Board of Directors shall not however, have the power to borrow any sum of money or mortgage any assets of the Club with or without collateral security, without first obtaining the approval of the Members of the Club as provided in these By-Laws.&lt;br /&gt;
===Section 9===&lt;br /&gt;
The Board of Directors shall have the power to enter into contracts for and on behalf of the Club and to designate one or more Members to sign any such contract.&lt;br /&gt;
===Section 10===&lt;br /&gt;
All current members of the Board of Directors shall have unlimited guest passes during their term.&lt;br /&gt;
===Section 11===&lt;br /&gt;
In consideration of service to the club, outgoing Board Members who have served a two year term and have attended 80% of the scheduled Board meetings during their term, shall receive complimentary membership dues&lt;br /&gt;
the year following their two year term. The past Board Member shall be responsible for the Capital Assessment Fee. The Swim Team Coordinators who are serving on a three year term shall receive complimentary membership dues following the first two years of their term provided they attend 80% of the meetings during the first two years. The Swim Team Coordinators shall also receive complimentary membership dues after serving as coordinators during the season which Fairway Farms hosts League Meet and provided they attend 80% of the meetings during that season. They shall also be responsible for the Capital Assessment Fee. No other compensation shall be received by any Board Members.&lt;br /&gt;
==ARTICLE V - OFFICERS==&lt;br /&gt;
===Section 1===&lt;br /&gt;
The President shall preside at all meetings of the Club and of the Board of Directors. He shall be the administrative officer of the Club. He shall appoint, subject to confirmation by the Board of Directors special committees. He shall be, ex-officio, a Member of all committees.&lt;br /&gt;
===Section 2===&lt;br /&gt;
The Vice-President, in the absence or temporary disability of the President, shall act in the President&#039;s stead. The [[Board Vice President|Vice President]] shall under the direction of the President, attend to the business and financial operations of the Club and shall be, ex-officio, a Member of all committees. After serving one year as [[Board Vice President|Vice President]], the [[Board Vice President|Vice President]] shall serve as President for the following year. If the [[Board Vice President|Vice President]] is then unable or unwilling to assume the office of President, a President shall be elected by the Members of the Club in the manner prescribed by the By-Laws.&lt;br /&gt;
===Section 3===&lt;br /&gt;
The Secretary or designate, shall send out the notices of the meetings of the Club and of the Board of Directors; keep the Minutes; mail any Club newsletter and the dues notices; and attend to the correspondence pertaining to such office. The Secretary shall perform such other duties pertaining to the office as may be asked by the Board of Directors.&lt;br /&gt;
===Section 4===&lt;br /&gt;
The Treasurer and Vice Treasurer shall attend to keeping the accounts of the Club, collecting its revenues, and paying its bills as approved by the Board of Directors or other agency authorized by the Board to incur them. The Treasurer shall deposit funds of the Club received by the Treasurer, in the name of the Club in such depository as may be authorized by the Board. The Treasurer shall perform such other duties pertaining to his office as may be asked by the Board.&lt;br /&gt;
===Section 5===&lt;br /&gt;
In the event of the death, resignation or incapacity of any of the Club officers, the Board of Directors shall select a successor who shall serve out such unexpired term.&lt;br /&gt;
==ARTICLE VI - MEMBERSHIP==&lt;br /&gt;
===Section 1===&lt;br /&gt;
The Membership of the Club shall be of three (3) classes, Active, Empty Nester, and Associate. Active memberships shall be limited to a maximum of three hundred fifty-five (355). Empty Nester and Associate memberships shall be limited to a number determined by the Board of Directors from time to time in its discretion.&lt;br /&gt;
&lt;br /&gt;
===Section 2===&lt;br /&gt;
An Active Member shall consist of those persons, not to exceed two (2), holding a Certificate of Membership and their unmarried children residing in their home. Proof of residency for unmarried adult children may be requested by the Membership Chair. Certificate of Membership shall be issued to no more than two adult names living in the same household. The Certificate shall provide for a right of survivorship.&lt;br /&gt;
===Section 3===&lt;br /&gt;
Section 3a - &lt;br /&gt;
An Empty Nester Member shall consist of those persons, not to exceed two (2), holding a certificate of membership. To qualify as an Empty Nester Member, both persons must live in the same household, and have been an Active Member of Fairway Farms Swim Club for a minimum of 10 years. Empty Nester Members cannot have an Associate Membership added. Empty Nester Memberships can only be converted from existing Active Memberships that have been in good standing with the club for a minimum of 10 years. Empty Nester bond conversion requests shall be approved by the Board of Directors on a case-by-case basis. Once an Active Membership has been converted to an Empty Nester Membership, an Active Membership will be made available to the next family on the waitlist. Should an Empty Nester Membership wish to convert back to an Active Membership, the member will notify the Membership Chairperson and their name will be placed at the end of the waitlist at the time notice is given.&lt;br /&gt;
&lt;br /&gt;
Section 3b - &lt;br /&gt;
An Associate Member is defined as a relative or other person associated with an Active Member (Mother, Father, Stepdaughter, Stepson, Nephew, Niece, Grandchild, etc), as approved by the Board of Directors in its sole and unfettered discretion. The terms and conditions of any Associate membership (including the amount of dues and fees payable for such membership and the term of such membership) shall be determined by the Board of Directors. An Associate membership may not be sold, assigned or transferred.&lt;br /&gt;
&lt;br /&gt;
===Section 4===&lt;br /&gt;
Any Member of any class may, for cause and after having been given an opportunity for a hearing, be suspended or have their membership bond revoked. A suspension shall not be for a period exceeding three months and during a suspension there shall be no refund of club dues. A revocation shall be immediately effective and the membership shall be sold in accordance with these By-Laws after which the bond and any dues to be refunded under Article VII(e)(f) shall be paid to the Member. A suspension or revocation shall require a two-thirds (2/3) vote of the Members of the Board of Directors present at any meeting thereof. Cause of suspension shall, in general, consist of violation of these By-Laws or of the rules or regulations of the club, or seriously objectionable or offensive conduct. Revocation of a Membership shall be for repeated offenders or for extraordinarily objectionable and offensive conduct.&lt;br /&gt;
===Section 5===&lt;br /&gt;
The Board of Directors has the power to suspend Club privileges for the violation of Club rules and regulations. A report of Club violations containing reasons therefore, shall be submitted to the President within 24 hours. The Board of Directors may delegate to the Manager or Assistant Manager of the Club the power to suspend Club privileges of Members under 18 years of age provided such suspension does not exceed seven (7) days. Suspension for more than one day will require notification of the President, Vice-President or other Board Member.&lt;br /&gt;
===Section 6===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;All Members of the Club shall be accorded the facilities of the Club subject to its rules and regulations.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Board of Directors shall by rule, fix the terms and conditions upon which guests of Members may use the facilities of the Club.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Any property of the Club broken or damaged by a Member of any class, or his guest, shall be promptly paid for by the responsible Member. No person shall take any article belonging to the Club without written permission of a person designated by the Club.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Club assumes no responsibility and Members or their guests can have no claim against the Club, for property of Members of any class, or any guest, which may be brought into or left in&amp;quot; the Club buildings, or on the grounds.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==ARTICLE VII - DUES AND FEES AND MEMBERSHIP CERTIFICATES==&lt;br /&gt;
===Section 1===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The annual dues of Fairway Farms are $585. These dues, along with the capital assessment fee as described in Article VII, Section 1(g) are due by March 15 of each year. A member may also pay dues in monthly installments of $200.00 each, with the first installment being due on March 1. The member who wishes to pay in monthly installments shall submit three checks payable to Fairway Farms, dated March 1, April 1 and May 1, and submit all three checks prior to March 1. The club will hold these three checks and present them to the bank for payment after the check dates. The member may either submit a fourth check dated March 15 for the capital assessment, or may add the capital assessment to the first check dated March 1. No installment payments will be accepted without the capital assessment check. Under either option, the envelope must be postmarked by the due date in order to avoid late fees.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;At the beginning of each year the Board of Directors shall establish dues and fees for each class of membership for the ensuing year. However, without the approval of the membership, the Board of Directors may not increase the dues and fees for any year by more than 10% from the immediately preceding year and in any case by more than 25% in the aggregate in any 5 year period.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dues and fees shall be sufficient to provide for the necessary operating expenses of the Club and the proper maintenance and improvement of its property, and such dues and fees shall be payable by such date as the Board of Directors shall determine (the &amp;quot;Due Date&amp;quot;). Any member who does not submit payment as described in section 1(a) or other indebtedness shall be subject to a 15% penalty of such delinquent amount and the same shall become immediately due and payable. Until such time as all such fees, dues, indebtedness, and penalties are “paid in full,” the Member shall be denied use of all Club facilities for that year’s season. Under no circumstances shall a member that is not “paid in full” be admitted to the club or participate in club activities.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Any special assessment proposed by the Board of Directors for any purpose shall require the vote of the Active Members at an Annual or Special Meeting called for that purpose.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;No dues or fees or any part thereof shall be refunded in the event pool operations are required to be suspended for any period. In the event of a sale or transfer of membership subsequent to the due date of any year, that year’s dues and fees will be refunded on the basis of the proportion of dues and fees that the new member must pay to the Club pursuant to Article VII(1)(f).&lt;br /&gt;
&amp;lt;li&amp;gt;Any person acquiring membership after the due date of any year shall pay Dues and Fees for that year on the following basis:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Due Date through June 15 = 100% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;June 16 through June 30 = 80% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;July 1 through July 15 = 60% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;July 16 through July 31= 40% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;August 1 through August 15 20% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;August 16 through close of Club for the season - no Dues or Fees required.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Provided that the total amount of Dues and Fees paid by the former Member and the new Member shall not exceed the total amount of Dues and Fees payable to the Club for the year for each membership.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;A Capital Improvement Fee of one hundred fifty dollars ($150) is to be paid by each member in cash or other conditions as established from time to time by the Board of Directors as pursuant to the vote of the members at the General Membership meeting held in 2020 and continuing on a yearly basis until amended as outlined in this Article. The Capital Improvement Fee will be used toward pool renovations and other improvements or repairs necessary to function as voted by the Board of Directors.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;A Capital Recovery Improvement Fee of one hundred dollars ($100) beginning fiscal year 2022 (which begins December 1, 2021) and beyond is to be paid by each new Member Bond in cash or other conditions as established from time to time by the Board of Directors.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Section 2===&lt;br /&gt;
Candidates for Active membership in the Club may be required to pay a nonrefundable application fee upon making application for membership. Moreover all applicants for Active and Associate Membership in the Club shall be required to pay a non-refundable initiation fee upon being granted membership. Notwithstanding the provisions of Article VII Section I (a) to the contrary, the amount of the application fee, if any, and the amount of the initiation fee shall be determined by the Board of Directors from time to time provided however, the amount of the initiation fee shall not exceed $50.00.&lt;br /&gt;
===Section 3===&lt;br /&gt;
As a condition to Active Membership, a Certificate of Membership shall be purchased. All such Certificates shall be sold for the sum of $650.00 cash. Initiation fees, dues and other fees shall be in addition to the cost of the Certificate of Membership.&lt;br /&gt;
===Section 4===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If an Active Member desires to sell, assign, transfer or in any manner, dispose of a Certificate of Membership, such Member must first offer to sell the Certificate to the Club in writing. The Club shall then have thirty (30) days within which to accept the offer. Such Member may withdraw said offer at any time before the Club accepts the offer by providing the Club with written notice thereof. If the Club accepts the offer, it shall provide notice thereof to such Member and Within 30 days of such notice, the Club shall tender the agreed upon sum to such Member whereupon; the Certificate of Membership shall be surrendered to the Club.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the Club fails to accept any such offer to sell within thirty (30) days of receipt of such offer or the Club, having duly accepted the offer, fails to tender the repurchase price within thirty (30) days after notifying such Member of its acceptance, then in either such event, the restrictions on the sale of that particular Certificate of Membership shall terminate and the holder of the Certificate shall be free to sell or transfer the Certificate upon the open market to any other person who is eligible for Active membership Linder these By-Laws and who shall pay the required initiation fee and dues.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the Active Member proposes to sell or lease such Member&#039;s residence, and desires the purchaser or lessee to have the first opportunity to acquire such Member&#039;s Certificate of Membership, then in that event, such Member&#039;s offer to sell the Certificate to the Club shall include a statement to this effect along with the name and address of the person purchasing or leasing the residence, and in such event, if the Club repurchases the Certificate of Membership, it shall offer such membership to the person purchasing or leasing such residence, for the sum of $650.00. Such person shall then have thirty (30) days to accept such offer. If such person accepts the offer, such person shall deliver written notice thereof to the Club and within 10 days of such notice, tender the sum of $650.00 to the Club and the required initiation fees and dues. If such person fails to accept such offer and pay the required sums, the Club shall be free to sell such membership to any eligible applicant.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Board of Directors may limit the periods of time during the year Certificates of Membership may be sold, assigned, transferred or otherwise disposed of. Moreover, in lieu of the Club purchasing any Certificate of Membership under this Article VII, the Board of Directors may require such Certificate be sold by the holder thereof directly to an applicant for membership designated by the Club. In such an event, such applicant shall pay such holder the sum of $650.00 whereupon, the holder shall surrender such Certificate to the Club and such applicant shall pay the required initiation fee and dues and other fees.&lt;br /&gt;
&amp;lt;li&amp;gt;If for any reason, a Certificate of Membership is not or cannot be tendered by any Member upon the sale, assignment, transfer, or other disposition thereof, the Club shall cancel such Certificate on it books and records and issue a replacement Certificate in which case, the date of such sale, assignment, transfer, or other disposition shall be deemed to be the date upon which the purchase price therefore is made available to the seller or transferor thereof.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 5===&lt;br /&gt;
All membership applications and transfers shall be subject to the approval of the Board of Directors or one of its Members designated by the Board for that purpose.&lt;br /&gt;
===Section 6===&lt;br /&gt;
Membership Certificates shall be transferable only on the books of the Club. All Certificates transferred in accordance with these By-Laws shall be tendered to the Secretary or any other designated person for cancellation and reissuance in the name of the transferee. For purposes of establishing an effective date, the transfer is deemed to take effect as of the date the Certificate is delivered to the Membership Chairperson or such other person.&lt;br /&gt;
===Section 7===&lt;br /&gt;
Upon dissolution of the Club, the assets of the Club shall be applied and distributed as:&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First, all liabilities and obligations of the Club shall be paid and discharged or adequate provision shall be made therefore.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Then, the remaining assets of the Club shall be liquidated and the proceeds thereof shall be distributed to the Active Members pro ratably. The Active Members shall be entitled to a pro rata distribution of the assets of the Club after payment of all debts and liquidation of all liabilities. Associate Members shall not share in any distribution and liquidation of assets.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 8===&lt;br /&gt;
The Club shall have a lien upon and charge against a Member’s Certificate of Membership for any and all unpaid fees, dues and other indebtedness owing to the Club by Member. The lien may be enforced by cancellation and sale of the Membership at such time as amounts remain unpaid as of May 1. In the event the Club is unable to obtain possession of the Certificate, it may be canceled upon the books of the Club, the membership may be sold, and a new Certificate issued to the purchaser thereof. In the event of the enforcement of a lien as herein provided, neither the signature of the holder nor delivery of the Certificate shall be required to perfect the transfer, and the Membership Chairperson of the Club is authorized as attorney of the holder of the Certificate, to make such transfer. In the event that the lien is satisfied by a cancellation and resale of the membership, the Club shall account to and pay over to the delinquent Member, the excess of the resale price over the indebtedness. Every Certificate of Membership issued is expressly subject to the provisions of this section.&lt;br /&gt;
===Section 9===&lt;br /&gt;
All fees and other charges mentioned herein are exclusive of all taxes imposed by State, Federal and other Government bodies and agencies.&lt;br /&gt;
===Section 10===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;In the event that a membership certificate is held jointly, and that relationship is terminated by divorce or legal separation, only one individual shall continue the membership and the Board of Directors will issue a new membership certificate in the name agreed to by the parties or as adjudged by a court of law upon receipt of a certified copy of the court order/judgment.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The individual not named on the new certificate shall be eligible for membership and shall immediately be placed at the front of the wait list, if one exists.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;In the event that a divorce or legal separation is final and no determination or agreement is made: the certificate may be terminated on the following March 1st and the certificate may be repurchased by the club. Each party shall be eligible to purchase a new membership and be placed at the front of the wait list, if one exists.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==ARTICLE VIII - MEMBERSHIP MEETINGS==&lt;br /&gt;
===Section 1===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Annual Meeting of the Club shall be held each calendar year on a date and at such place and time as the Board of Directors may determine.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Annual Meeting shall be for the purpose of electing Directors, presenting committee reports, and for the transaction of such other business as may be indicated in the notice.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 2===&lt;br /&gt;
Special Meetings of the Club may be called by the Board of Directors. Also, upon the written request of sixty (60) Members to the Secretary, stating the purpose therefore, a Special Meeting shall be called by the Secretary within thirty (30) days.&lt;br /&gt;
===Section 3===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Written notice of the Annual Meeting must be given to all Active Members not less than ten (10) days nor more than sixty (60) days prior to the date of the Meeting. Notice of the Annual Meeting shall indicate the number of Directors to be elected and the names of any Members known to the Board of Directors to be standing for election.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Written notice of any Special Meeting must be given to all Active Members not less than ten (10) days nor more than sixty (60) days prior to any Special Meeting. Notice of any Special Meeting shall state the purposes for which the Special Meeting is called, and no other business shall be transacted thereat.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 4===&lt;br /&gt;
Only Active Members shall be entitled to vote at meetings of the Club. Each Active membership shall be entitled to one vote. In cases where a Membership is in the name of more than one person, either, but not both, of such persons may vote. Voting may be in person, by proxy, by written ballot or by voice, but if by voice, ten (10) Members shall have the right to demand voting by roll call or in writing.&lt;br /&gt;
===Section 5===&lt;br /&gt;
Ten (10%) percent of the Active Members, present in person or by proxy at a meeting of the Club shall constitute a quorum. A majority vote of the Active Members present in person or by proxy at a constituted meeting shall be sufficient to carry a resolution or a motion.&lt;br /&gt;
===Section 6===&lt;br /&gt;
Candidates for election to the Board of Directors as a specific officer, representative or committee chairperson, shall stand for election as such and the candidate receiving a majority of the votes cast by Members entitled to vote thereon shall be so elected to such position. In the case of a tie, a second vote shall be taken. If a tie shall result from the second vote, a majority vote of the Board of Directors present in person at the meeting shall determine the winner and the first runner-up shall serve as an alternate in case the winner shall later resign or be removed during the term of office. Candidates for election to the Board of Directors at-large, shall all stand for election together. Directors for such at-large positions shall be elected by a plurality of the votes cast by Members entitled to vote thereon.&lt;br /&gt;
===Section 7===&lt;br /&gt;
A General Information Meeting may be held on a date and at such place and time as the board of Directors may determine. Written notice of a General Information Meeting must be given to all Active Members not less than ten (10) days nor more than sixty (60) days prior to any General Information Meeting. The purpose of the General Information Meeting may be to present the Budget for the Club for the ensuing year which the Board of Directors has approved and such other information as the Board may determine is appropriate for the general information of the membership. No quorum is required to constitute a General Information Meeting and no action may be taken thereat on a resolution, motion or any other matter.&lt;br /&gt;
===Section 8===&lt;br /&gt;
The Board of Directors may from time to time, adopt and prescribe reasonable procedures regarding the nomination and election of candidates to the Board of Directors, the submission of any matter to the vote of the membership, and the conducting of all Meetings of the Club. Roberts Rules of Order will prevail at all Meetings of the Club.&lt;br /&gt;
==ARTICLE IX - COMMITTEES==&lt;br /&gt;
===Section 1===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The standing committees shall be Buildings and Grounds, Social, Membership, Concessions and Swim Team.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The duties and powers assigned in these By-Laws to the standing committees shall be subject to the authority and modification of the Board of Directors. No Committee shall expend funds without prior appropriation by the Board of Directors.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 2===&lt;br /&gt;
The Buildings and Grounds Committee shall exercise supervision over the Pool/Buildings and Grounds; shall attend to the improvement and maintenance of the Pool/Buildings and Grounds and its operating equipment; shall have the authority thereover; and shall see that the rules and regulations of the Club relating to the Pool/ Buildings and Grounds are enforced.&lt;br /&gt;
===Section 3===&lt;br /&gt;
The Social Committee shall plan and supervise all parties and social functions for the Club.&lt;br /&gt;
===Section 4===&lt;br /&gt;
The Membership Committee shall exercise supervision over the inquiries, applications, approval, admittance and termination of all memberships in the Club; shall adopt and prescribe such procedures, as it deems appropriate for the orderly operation thereof; and shall collect all monies from new Members and remit the same to the Club.&lt;br /&gt;
===Section 5===&lt;br /&gt;
The Concessions Committee shall exercise supervision over the operation of the Concession area; shall have authority thereover; and shall procure the needed supplies and concessions.&lt;br /&gt;
===Section 6===&lt;br /&gt;
Such temporary committees as deemed necessary may be appointed by the Board of Directors and they shall terminate when the purpose of their formation has been fulfilled.&lt;br /&gt;
==ARTICLE X - INDEMNIFICATION: MISCELLANEOUS==&lt;br /&gt;
===Section 1===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Unless otherwise provided by law, the Club shall indemnify a person who was or is a party or is threatened to be made a party to a threatened, pending or completed action, suit, or proceeding, whether civil, criminal, administrative, or investigative and whether formal or informal, other than an action by or in the right of the Club, by reason of the fact that he or she is or was a director, officer, or employee of the Club, or is or was serving at the request of the Club as a director, officer, partner, trustee, employee, or agent of another foreign or domestic corporation, partnership, joint Venture, trust, or other enterprise, whether for profit or not, including attorneys&#039; fees, judgments, penalties, fines, and amounts paid in settlement actually and reasonably incurred by the person in connection with the action, suit or proceeding, if the person acted in good faith and in a manner the person reasonably believed to be in or not opposed to the best interests of the Club or its Members, and with respect to a criminal action or proceeding, if the person had no reasonable cause to believe his or her conduct was unlawful. The termination of any action, suit, or proceeding by judgment, order, settlement, conviction, or upon a plea of nolo contendere or its equivalent, does not, of itself, create a presumption that the person did not act in good faith and in a manner which he or she reasonably believed to be or not opposed to the best interests of the Club or its&lt;br /&gt;
Members, and with respect to a criminal action or proceeding, had reasonable cause to believe that his or her conduct was unlawful.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Unless otherwise provided by law, the Club shall indemnify any person who was or is a party to or is threatened to be made a party to a threatened, pending, or completed action or suit by or in the right of the Club to procure a judgment in its favor or by reason of the fact that he or she is or was a director, officer, or employee of the Club, or is or was serving at the request of the Club as a director, officer, partner, trustee, employee, or agent of another foreign or domestic corporation, partnership, joint venture, trust, or other enterprise, whether for profit or not, against expenses, including attorneys&#039; fees, and amounts paid in settlement actually and reasonably incurred by the person in connection with the action or suit, if the person acted in good faith and in a manner the person reasonably believed to be in or not opposed to the best interests of the Club or its Members. However, indemnification shall not be made for a claim, issue, or matter in which the person has been found liable to the Club unless and only to the&lt;br /&gt;
extent that the court in which the action or suit was brought has determined upon application that despite the adjudication of liability, but in view of all circumstances of the case, the person is fairly and reasonably entitled to indemnification for expenses which the court considers proper.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 2===&lt;br /&gt;
These By-Laws may be amended by a vote of the Active Members at any Meeting of the Club.&lt;br /&gt;
===Section 3===&lt;br /&gt;
Notwithstanding any provisions of these By-Laws to the contrary, no part of the net earnings of this club shall inure to the benefit of any member. An Active or Associate Member may be given consideration if he or she has proper background, training, thorough knowledge and applies for such position(s): (1) Fitness Instructor; (2) Diving Instructor; (3) Tennis Instructor; (4) Swim Coach, (5) Lifeguard or (6) Concession worker. Said position shall not be filled by a Board Member in his/her current term. Each position is considered “Contract” not “Ongoing”. Each position will be reconsidered on an annual basis.&lt;br /&gt;
&lt;br /&gt;
==Revision History==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Section&lt;br /&gt;
!Comment&lt;br /&gt;
|Article &lt;br /&gt;
|-&lt;br /&gt;
|January 2024&lt;br /&gt;
|Article VII, Section 1, g&lt;br /&gt;
|A delayed update to the bylaws to reflect the increased capital fee from $100 to $150 per an August 15th, 2023 vote by General Membership.&lt;br /&gt;
|-&lt;br /&gt;
|February 2023&lt;br /&gt;
|Article VII Section 1&lt;br /&gt;
|Increased annual dues from $550 to $585 (+6.3%) per a February 13th, 2023 board vote.&lt;br /&gt;
|-&lt;br /&gt;
|August 2022&lt;br /&gt;
|Article IV Section 1&lt;br /&gt;
|Added a Vice Treasurer position by vote of General Membership on August 16, 2022.&lt;br /&gt;
|-&lt;br /&gt;
|September 2022&lt;br /&gt;
|Article VII Section 1&lt;br /&gt;
|A delayed update to the bylaws to identify an increase in the annual dues from $525 to $550 (+4.8%) per a January 10th, 2022 board vote.&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=4|August 2020&lt;br /&gt;
|Article III Section 2&lt;br /&gt;
|Changed swim team coordinator terms (alignment for the lost 2020 season) per approval by the board and members at the 2020 annual meeting.&lt;br /&gt;
|-&lt;br /&gt;
|Article VI Section 1&lt;br /&gt;
|Increased the number of member bonds from 330 to 340 per approval by the board and members at the 2020 annual meeting.&lt;br /&gt;
|-&lt;br /&gt;
|Article VII Section 1, g&lt;br /&gt;
|Increased the capital fee from $75 to $100 per approval by the board and members at the 2020 annual meeting.&lt;br /&gt;
|-&lt;br /&gt;
|Article VII Section 1, h (added)&lt;br /&gt;
|Added the Capital Recovery fee of $100 per approval by the board and members at the 2020 annual meeting.&lt;br /&gt;
|-&lt;br /&gt;
|August 2020&lt;br /&gt;
|&lt;br /&gt;
|Document Transferred to Wiki&lt;br /&gt;
|-&lt;br /&gt;
|August 2019&lt;br /&gt;
|Article VI Section 2&amp;lt;br/&amp;gt;Article VII Section 10&lt;br /&gt;
|General Member Approval Vote&lt;br /&gt;
|-&lt;br /&gt;
|June 2018&lt;br /&gt;
|Article III, Section 2&amp;lt;br/&amp;gt;Article IV, Section 11&amp;lt;br/&amp;gt;Article VI, Section 2&amp;lt;br/&amp;gt;Article VII, Section 1(a), Section 1(e), Section 1(f), Section 8&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Feb 2017&lt;br /&gt;
|Article VII, Section 1(a)&lt;br /&gt;
|Amended Membership Dues fee per Board Member Vote&lt;br /&gt;
|-&lt;br /&gt;
|Sep 2016&lt;br /&gt;
|Article VI, Section 4&lt;br /&gt;
|Amended per Aug 2016 General Member Approval Vote&lt;br /&gt;
|-&lt;br /&gt;
|Feb 2016&lt;br /&gt;
|Article X, Section 3&lt;br /&gt;
|Amended per Aug 2015 General Member Approval Vote&lt;br /&gt;
|-&lt;br /&gt;
|Aug 2012&lt;br /&gt;
|&lt;br /&gt;
|Document Amended and Approved&lt;br /&gt;
|-&lt;br /&gt;
|Aug 2011&lt;br /&gt;
|&lt;br /&gt;
|Document Amended and Approved&lt;br /&gt;
|-&lt;br /&gt;
|Sep 2004&lt;br /&gt;
|&lt;br /&gt;
|Entire Document Scanned and Re-Formatted into Word&lt;br /&gt;
|-&lt;br /&gt;
|July 2000&lt;br /&gt;
|&lt;br /&gt;
|Entire Document Revised&lt;br /&gt;
|-&lt;br /&gt;
|Nov 6, 1991&lt;br /&gt;
|&lt;br /&gt;
|Entire Document Developed By-Laws Document&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Bylaws&amp;diff=1747</id>
		<title>Bylaws</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Bylaws&amp;diff=1747"/>
		<updated>2024-01-25T16:24:47Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;AMENDED AND RESTATED BY-LAWS OF THE FAIRWAY FARMS SWIM AND TENNIS CLUB AS OF AUGUST 16, 2022.&lt;br /&gt;
==ARTICLE I - NAME==&lt;br /&gt;
The name of this Corporation shall be the FAIRWAY FARMS SWIM AND TENNIS CLUB, hereinafter referred to as the &amp;quot;CLUB&amp;quot;.&lt;br /&gt;
==ARTICLE II - PURPOSE ==&lt;br /&gt;
The purpose for which the Club is formed is to operate a swimming pool and other recreational and social facilities, in the City of Livonia, State of Michigan, for the benefit of the Members, and to sell memberships in the Club to residents of Livonia and bordering communities. For purposes of this Article, the term &amp;quot;bordering communities&amp;quot; shall mean those cities and townships that touch any border of Livonia (including those cities within a township touching any border of Livonia). The exact number of Members in the Club who are not Livonia residents shall be determined from time to time by the Board of Directors.&lt;br /&gt;
However, in no case shall the total number of Members who are not Livonia residents ever exceed forty percent (40%) of the total membership at any one time. This limitation shall not, however, affect the status of any Member in the Club who is not a Livonia resident once that Member is admitted to the Club unless that Member moves out of a bordering community. In determining the exact number of Members in the Club who are not Livonia residents, the Board of Directors shall give full consideration to the number of Livonia residents waiting for membership in the Club and shall give those Livonia residents such preference over other applicants from bordering communities that the Board of Directors shall consider appropriate.&lt;br /&gt;
==ARTICLE III - GOVERNMENT==&lt;br /&gt;
===Section 1===&lt;br /&gt;
The Club shall be managed by a Board of Directors of at least four (4) and no more than thirteen (13) in number, the exact number of which shall be determined by the Board of Directors from time to time. In addition to this number, the Manager of the Pool shall be an Advisory Director and shall be entitled to all the rights and privileges of that position except, the Manager shall not be entitled to vote nor shall his presence at any meeting of the Board of Directors count towards establishing a required quorum.&lt;br /&gt;
===Section 2===&lt;br /&gt;
At each annual meeting of the Active Members of the Club, the [[Board Vice President|Vice President]] and alternatively, one-half of the other directors shall be elected each year from among the Active members. The President and [[Board Vice President|Vice President]] shall each serve a term of one year and all the other Directors shall serve for a term of two years (except as otherwise provided in Article VIII, Section 6) and until their successors have been chosen. The two Swim Team Coordinator positions shall be elected together and shall serve a term of two years in 2021 and 2022, 2023 and 2024, and 2025 and 2026. The next Swim Team Coordinator term shall be for three years in 2027, 2028 and 2029 and shall continue to alternate on two year then three-year terms. Any person elected to the Board of Directors for a particular office or committee shall not be entitled to serve a successive term for the same office or committee unless such person was elected to fill a vacancy in such office or committee or no one else in standing for election to such office or committee and the Board of Directors asks such person to serve again, in which case, such person can serve a successive term.&lt;br /&gt;
===Section 3===&lt;br /&gt;
Any Member of the Board of Directors who shall cease to hold Active Membership in the Club automatically shall cease to be a Member of the Board of Directors. Except as otherwise provided in Article VIII, Section 6, vacancies in the Board of Directors shall be appointed by the remaining Members of the Board, though less than a quorum, and each person so appointed shall be a Director until his successor is elected by the Members at the next annual meeting.&lt;br /&gt;
==ARTICLE IV - BOARD OF DIRECTORS==&lt;br /&gt;
===Section 1===&lt;br /&gt;
The Board of Directors shall consist of a President, a [[Board Vice President|Vice President]], a Secretary, a Treasurer and Vice Treasurer and such other representatives and chairpersons of committees, as the Board of Directors shall deem appropriate.&lt;br /&gt;
===Section 2===&lt;br /&gt;
The Board of Directors shall transact all Club business and shall have the authority to make and amend rules and regulations for the operation of Club and the Club&#039;s facilities. It may appoint and remove such clerks, agents; servants or employees as it may deem necessary and may fix their duties and compensation. The Board may constitute and appoint committees and define the powers and duties of the same.&lt;br /&gt;
===Section 3===&lt;br /&gt;
The Board of Directors shall designate the bank or banks in which the funds of the Club shall be deposited and determine the manner in which checks, drafts and other instruments for the payment of funds of the Club shall be executed.&lt;br /&gt;
===Section 4===&lt;br /&gt;
Any Member of the Board of Directors may be removed from office by the Members of the Club at a Special Meeting called in accordance with these By-Laws.&lt;br /&gt;
===Section 5===&lt;br /&gt;
The Board of Directors shall cause the books of the Club to be reviewed and prepared annually by Certified Public Accountants, selected by the Board, who shall neither be Members of the Board of Directors nor officers of the Club, and the report of the accountants shall be available to the Members upon request.&lt;br /&gt;
===Section 6===&lt;br /&gt;
The Board of Directors shall meet at least once a month during the months of January, February, March, April, May, June, July, August, September and October and at such other times, as it may deem appropriate. The Board shall be presided over by the President; in his absence the Board shall be presided over by the Vice-President. A majority of the Members of the Board present in person shall constitute a quorum. Voting members of the Board of Directors shall consist of the President, [[Board Vice President|Vice President]], Treasurer, Secretary, Membership and one representative from Building and Grounds, Social, Concessions and Swim Team. Members of such committees must reach a consensus or that committee will abstain from the vote. A majority vote of the Board Members present at a properly constituted meeting shall be required to carry a resolution or motion. Special meetings may be called by the President and shall be called by the Secretary upon the request of two (2) Members of the Board.&lt;br /&gt;
===Section 7===&lt;br /&gt;
In the event a question before the Board of Directors results in a tie vote, which cannot be resolved, the question may then be submitted to the membership for decision.&lt;br /&gt;
===Section 8===&lt;br /&gt;
The Board of Directors shall have the power to make such expenditures from available cash, as it considers appropriate. The Board of Directors shall not however, have the power to borrow any sum of money or mortgage any assets of the Club with or without collateral security, without first obtaining the approval of the Members of the Club as provided in these By-Laws.&lt;br /&gt;
===Section 9===&lt;br /&gt;
The Board of Directors shall have the power to enter into contracts for and on behalf of the Club and to designate one or more Members to sign any such contract.&lt;br /&gt;
===Section 10===&lt;br /&gt;
All current members of the Board of Directors shall have unlimited guest passes during their term.&lt;br /&gt;
===Section 11===&lt;br /&gt;
In consideration of service to the club, outgoing Board Members who have served a two year term and have attended 80% of the scheduled Board meetings during their term, shall receive complimentary membership dues&lt;br /&gt;
the year following their two year term. The past Board Member shall be responsible for the Capital Assessment Fee. The Swim Team Coordinators who are serving on a three year term shall receive complimentary membership dues following the first two years of their term provided they attend 80% of the meetings during the first two years. The Swim Team Coordinators shall also receive complimentary membership dues after serving as coordinators during the season which Fairway Farms hosts League Meet and provided they attend 80% of the meetings during that season. They shall also be responsible for the Capital Assessment Fee. No other compensation shall be received by any Board Members.&lt;br /&gt;
==ARTICLE V - OFFICERS==&lt;br /&gt;
===Section 1===&lt;br /&gt;
The President shall preside at all meetings of the Club and of the Board of Directors. He shall be the administrative officer of the Club. He shall appoint, subject to confirmation by the Board of Directors special committees. He shall be, ex-officio, a Member of all committees.&lt;br /&gt;
===Section 2===&lt;br /&gt;
The Vice-President, in the absence or temporary disability of the President, shall act in the President&#039;s stead. The [[Board Vice President|Vice President]] shall under the direction of the President, attend to the business and financial operations of the Club and shall be, ex-officio, a Member of all committees. After serving one year as [[Board Vice President|Vice President]], the [[Board Vice President|Vice President]] shall serve as President for the following year. If the [[Board Vice President|Vice President]] is then unable or unwilling to assume the office of President, a President shall be elected by the Members of the Club in the manner prescribed by the By-Laws.&lt;br /&gt;
===Section 3===&lt;br /&gt;
The Secretary or designate, shall send out the notices of the meetings of the Club and of the Board of Directors; keep the Minutes; mail any Club newsletter and the dues notices; and attend to the correspondence pertaining to such office. The Secretary shall perform such other duties pertaining to the office as may be asked by the Board of Directors.&lt;br /&gt;
===Section 4===&lt;br /&gt;
The Treasurer and Vice Treasurer shall attend to keeping the accounts of the Club, collecting its revenues, and paying its bills as approved by the Board of Directors or other agency authorized by the Board to incur them. The Treasurer shall deposit funds of the Club received by the Treasurer, in the name of the Club in such depository as may be authorized by the Board. The Treasurer shall perform such other duties pertaining to his office as may be asked by the Board.&lt;br /&gt;
===Section 5===&lt;br /&gt;
In the event of the death, resignation or incapacity of any of the Club officers, the Board of Directors shall select a successor who shall serve out such unexpired term.&lt;br /&gt;
==ARTICLE VI - MEMBERSHIP==&lt;br /&gt;
===Section 1===&lt;br /&gt;
The Membership of the Club shall be of three (3) classes, Active, Empty Nester, and Associate. Active memberships shall be limited to a maximum of three hundred fifty-five (355). Empty Nester and Associate memberships shall be limited to a number determined by the Board of Directors from time to time in its discretion.&lt;br /&gt;
&lt;br /&gt;
===Section 2===&lt;br /&gt;
An Active Member shall consist of those persons, not to exceed two (2), holding a Certificate of Membership and their unmarried children residing in their home. Proof of residency for unmarried adult children may be requested by the Membership Chair. Certificate of Membership shall be issued to no more than two adult names living in the same household. The Certificate shall provide for a right of survivorship.&lt;br /&gt;
===Section 3===&lt;br /&gt;
Section 3a - &lt;br /&gt;
An Empty Nester Member shall consist of those persons, not to exceed two (2), holding a certificate of membership. To qualify as an Empty Nester Member, both persons must live in the same household, and have been an Active Member of Fairway Farms Swim Club for a minimum of 10 years. Empty Nester Members cannot have an Associate Membership added. Empty Nester Memberships can only be converted from existing Active Memberships that have been in good standing with the club for a minimum of 10 years. Empty Nester bond conversion requests shall be approved by the Board of Directors on a case-by-case basis. Once an Active Membership has been converted to an Empty Nester Membership, an Active Membership will be made available to the next family on the waitlist. Should an Empty Nester Membership wish to convert back to an Active Membership, the member will notify the Membership Chairperson and their name will be placed at the end of the waitlist at the time notice is given.&lt;br /&gt;
&lt;br /&gt;
Section 3b - &lt;br /&gt;
An Associate Member is defined as a relative or other person associated with an Active Member (Mother, Father, Stepdaughter, Stepson, Nephew, Niece, Grandchild, etc), as approved by the Board of Directors in its sole and unfettered discretion. The terms and conditions of any Associate membership (including the amount of dues and fees payable for such membership and the term of such membership) shall be determined by the Board of Directors. An Associate membership may not be sold, assigned or transferred.&lt;br /&gt;
&lt;br /&gt;
===Section 4===&lt;br /&gt;
Any Member of any class may, for cause and after having been given an opportunity for a hearing, be suspended or have their membership bond revoked. A suspension shall not be for a period exceeding three months and during a suspension there shall be no refund of club dues. A revocation shall be immediately effective and the membership shall be sold in accordance with these By-Laws after which the bond and any dues to be refunded under Article VII(e)(f) shall be paid to the Member. A suspension or revocation shall require a two-thirds (2/3) vote of the Members of the Board of Directors present at any meeting thereof. Cause of suspension shall, in general, consist of violation of these By-Laws or of the rules or regulations of the club, or seriously objectionable or offensive conduct. Revocation of a Membership shall be for repeated offenders or for extraordinarily objectionable and offensive conduct.&lt;br /&gt;
===Section 5===&lt;br /&gt;
The Board of Directors has the power to suspend Club privileges for the violation of Club rules and regulations. A report of Club violations containing reasons therefore, shall be submitted to the President within 24 hours. The Board of Directors may delegate to the Manager or Assistant Manager of the Club the power to suspend Club privileges of Members under 18 years of age provided such suspension does not exceed seven (7) days. Suspension for more than one day will require notification of the President, Vice-President or other Board Member.&lt;br /&gt;
===Section 6===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;All Members of the Club shall be accorded the facilities of the Club subject to its rules and regulations.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Board of Directors shall by rule, fix the terms and conditions upon which guests of Members may use the facilities of the Club.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Any property of the Club broken or damaged by a Member of any class, or his guest, shall be promptly paid for by the responsible Member. No person shall take any article belonging to the Club without written permission of a person designated by the Club.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Club assumes no responsibility and Members or their guests can have no claim against the Club, for property of Members of any class, or any guest, which may be brought into or left in&amp;quot; the Club buildings, or on the grounds.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==ARTICLE VII - DUES AND FEES AND MEMBERSHIP CERTIFICATES==&lt;br /&gt;
===Section 1===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The annual dues of Fairway Farms are $585. These dues, along with the capital assessment fee as described in Article VII, Section 1(g) are due by March 15 of each year. A member may also pay dues in monthly installments of $200.00 each, with the first installment being due on March 1. The member who wishes to pay in monthly installments shall submit three checks payable to Fairway Farms, dated March 1, April 1 and May 1, and submit all three checks prior to March 1. The club will hold these three checks and present them to the bank for payment after the check dates. The member may either submit a fourth check dated March 15 for the capital assessment, or may add the capital assessment to the first check dated March 1. No installment payments will be accepted without the capital assessment check. Under either option, the envelope must be postmarked by the due date in order to avoid late fees.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;At the beginning of each year the Board of Directors shall establish dues and fees for each class of membership for the ensuing year. However, without the approval of the membership, the Board of Directors may not increase the dues and fees for any year by more than 10% from the immediately preceding year and in any case by more than 25% in the aggregate in any 5 year period.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dues and fees shall be sufficient to provide for the necessary operating expenses of the Club and the proper maintenance and improvement of its property, and such dues and fees shall be payable by such date as the Board of Directors shall determine (the &amp;quot;Due Date&amp;quot;). Any member who does not submit payment as described in section 1(a) or other indebtedness shall be subject to a 15% penalty of such delinquent amount and the same shall become immediately due and payable. Until such time as all such fees, dues, indebtedness, and penalties are “paid in full,” the Member shall be denied use of all Club facilities for that year’s season. Under no circumstances shall a member that is not “paid in full” be admitted to the club or participate in club activities.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Any special assessment proposed by the Board of Directors for any purpose shall require the vote of the Active Members at an Annual or Special Meeting called for that purpose.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;No dues or fees or any part thereof shall be refunded in the event pool operations are required to be suspended for any period. In the event of a sale or transfer of membership subsequent to the due date of any year, that year’s dues and fees will be refunded on the basis of the proportion of dues and fees that the new member must pay to the Club pursuant to Article VII(1)(f).&lt;br /&gt;
&amp;lt;li&amp;gt;Any person acquiring membership after the due date of any year shall pay Dues and Fees for that year on the following basis:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Due Date through June 15 = 100% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;June 16 through June 30 = 80% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;July 1 through July 15 = 60% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;July 16 through July 31= 40% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;August 1 through August 15 20% of Dues and Fees&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;August 16 through close of Club for the season - no Dues or Fees required.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Provided that the total amount of Dues and Fees paid by the former Member and the new Member shall not exceed the total amount of Dues and Fees payable to the Club for the year for each membership.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;A Capital Improvement Fee of one hundred fifty dollars ($150) is to be paid by each member in cash or other conditions as established from time to time by the Board of Directors as pursuant to the vote of the members at the General Membership meeting held in 2020 and continuing on a yearly basis until amended as outlined in this Article. The Capital Improvement Fee will be used toward pool renovations and other improvements or repairs necessary to function as voted by the Board of Directors.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;A Capital Recovery Improvement Fee of one hundred dollars ($100) beginning fiscal year 2022 (which begins December 1, 2021) and beyond is to be paid by each new Member Bond in cash or other conditions as established from time to time by the Board of Directors.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Section 2===&lt;br /&gt;
Candidates for Active membership in the Club may be required to pay a nonrefundable application fee upon making application for membership. Moreover all applicants for Active and Associate Membership in the Club shall be required to pay a non-refundable initiation fee upon being granted membership. Notwithstanding the provisions of Article VII Section I (a) to the contrary, the amount of the application fee, if any, and the amount of the initiation fee shall be determined by the Board of Directors from time to time provided however, the amount of the initiation fee shall not exceed $50.00.&lt;br /&gt;
===Section 3===&lt;br /&gt;
As a condition to Active Membership, a Certificate of Membership shall be purchased. All such Certificates shall be sold for the sum of $650.00 cash. Initiation fees, dues and other fees shall be in addition to the cost of the Certificate of Membership.&lt;br /&gt;
===Section 4===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If an Active Member desires to sell, assign, transfer or in any manner, dispose of a Certificate of Membership, such Member must first offer to sell the Certificate to the Club in writing. The Club shall then have thirty (30) days within which to accept the offer. Such Member may withdraw said offer at any time before the Club accepts the offer by providing the Club with written notice thereof. If the Club accepts the offer, it shall provide notice thereof to such Member and Within 30 days of such notice, the Club shall tender the agreed upon sum to such Member whereupon; the Certificate of Membership shall be surrendered to the Club.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the Club fails to accept any such offer to sell within thirty (30) days of receipt of such offer or the Club, having duly accepted the offer, fails to tender the repurchase price within thirty (30) days after notifying such Member of its acceptance, then in either such event, the restrictions on the sale of that particular Certificate of Membership shall terminate and the holder of the Certificate shall be free to sell or transfer the Certificate upon the open market to any other person who is eligible for Active membership Linder these By-Laws and who shall pay the required initiation fee and dues.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the Active Member proposes to sell or lease such Member&#039;s residence, and desires the purchaser or lessee to have the first opportunity to acquire such Member&#039;s Certificate of Membership, then in that event, such Member&#039;s offer to sell the Certificate to the Club shall include a statement to this effect along with the name and address of the person purchasing or leasing the residence, and in such event, if the Club repurchases the Certificate of Membership, it shall offer such membership to the person purchasing or leasing such residence, for the sum of $650.00. Such person shall then have thirty (30) days to accept such offer. If such person accepts the offer, such person shall deliver written notice thereof to the Club and within 10 days of such notice, tender the sum of $650.00 to the Club and the required initiation fees and dues. If such person fails to accept such offer and pay the required sums, the Club shall be free to sell such membership to any eligible applicant.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Board of Directors may limit the periods of time during the year Certificates of Membership may be sold, assigned, transferred or otherwise disposed of. Moreover, in lieu of the Club purchasing any Certificate of Membership under this Article VII, the Board of Directors may require such Certificate be sold by the holder thereof directly to an applicant for membership designated by the Club. In such an event, such applicant shall pay such holder the sum of $650.00 whereupon, the holder shall surrender such Certificate to the Club and such applicant shall pay the required initiation fee and dues and other fees.&lt;br /&gt;
&amp;lt;li&amp;gt;If for any reason, a Certificate of Membership is not or cannot be tendered by any Member upon the sale, assignment, transfer, or other disposition thereof, the Club shall cancel such Certificate on it books and records and issue a replacement Certificate in which case, the date of such sale, assignment, transfer, or other disposition shall be deemed to be the date upon which the purchase price therefore is made available to the seller or transferor thereof.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 5===&lt;br /&gt;
All membership applications and transfers shall be subject to the approval of the Board of Directors or one of its Members designated by the Board for that purpose.&lt;br /&gt;
===Section 6===&lt;br /&gt;
Membership Certificates shall be transferable only on the books of the Club. All Certificates transferred in accordance with these By-Laws shall be tendered to the Secretary or any other designated person for cancellation and reissuance in the name of the transferee. For purposes of establishing an effective date, the transfer is deemed to take effect as of the date the Certificate is delivered to the Membership Chairperson or such other person.&lt;br /&gt;
===Section 7===&lt;br /&gt;
Upon dissolution of the Club, the assets of the Club shall be applied and distributed as:&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First, all liabilities and obligations of the Club shall be paid and discharged or adequate provision shall be made therefore.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Then, the remaining assets of the Club shall be liquidated and the proceeds thereof shall be distributed to the Active Members pro ratably. The Active Members shall be entitled to a pro rata distribution of the assets of the Club after payment of all debts and liquidation of all liabilities. Associate Members shall not share in any distribution and liquidation of assets.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 8===&lt;br /&gt;
The Club shall have a lien upon and charge against a Member’s Certificate of Membership for any and all unpaid fees, dues and other indebtedness owing to the Club by Member. The lien may be enforced by cancellation and sale of the Membership at such time as amounts remain unpaid as of May 1. In the event the Club is unable to obtain possession of the Certificate, it may be canceled upon the books of the Club, the membership may be sold, and a new Certificate issued to the purchaser thereof. In the event of the enforcement of a lien as herein provided, neither the signature of the holder nor delivery of the Certificate shall be required to perfect the transfer, and the Membership Chairperson of the Club is authorized as attorney of the holder of the Certificate, to make such transfer. In the event that the lien is satisfied by a cancellation and resale of the membership, the Club shall account to and pay over to the delinquent Member, the excess of the resale price over the indebtedness. Every Certificate of Membership issued is expressly subject to the provisions of this section.&lt;br /&gt;
===Section 9===&lt;br /&gt;
All fees and other charges mentioned herein are exclusive of all taxes imposed by State, Federal and other Government bodies and agencies.&lt;br /&gt;
===Section 10===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;In the event that a membership certificate is held jointly, and that relationship is terminated by divorce or legal separation, only one individual shall continue the membership and the Board of Directors will issue a new membership certificate in the name agreed to by the parties or as adjudged by a court of law upon receipt of a certified copy of the court order/judgment.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The individual not named on the new certificate shall be eligible for membership and shall immediately be placed at the front of the wait list, if one exists.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;In the event that a divorce or legal separation is final and no determination or agreement is made: the certificate may be terminated on the following March 1st and the certificate may be repurchased by the club. Each party shall be eligible to purchase a new membership and be placed at the front of the wait list, if one exists.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==ARTICLE VIII - MEMBERSHIP MEETINGS==&lt;br /&gt;
===Section 1===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Annual Meeting of the Club shall be held each calendar year on a date and at such place and time as the Board of Directors may determine.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The Annual Meeting shall be for the purpose of electing Directors, presenting committee reports, and for the transaction of such other business as may be indicated in the notice.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 2===&lt;br /&gt;
Special Meetings of the Club may be called by the Board of Directors. Also, upon the written request of sixty (60) Members to the Secretary, stating the purpose therefore, a Special Meeting shall be called by the Secretary within thirty (30) days.&lt;br /&gt;
===Section 3===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Written notice of the Annual Meeting must be given to all Active Members not less than ten (10) days nor more than sixty (60) days prior to the date of the Meeting. Notice of the Annual Meeting shall indicate the number of Directors to be elected and the names of any Members known to the Board of Directors to be standing for election.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Written notice of any Special Meeting must be given to all Active Members not less than ten (10) days nor more than sixty (60) days prior to any Special Meeting. Notice of any Special Meeting shall state the purposes for which the Special Meeting is called, and no other business shall be transacted thereat.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 4===&lt;br /&gt;
Only Active Members shall be entitled to vote at meetings of the Club. Each Active membership shall be entitled to one vote. In cases where a Membership is in the name of more than one person, either, but not both, of such persons may vote. Voting may be in person, by proxy, by written ballot or by voice, but if by voice, ten (10) Members shall have the right to demand voting by roll call or in writing.&lt;br /&gt;
===Section 5===&lt;br /&gt;
Ten (10%) percent of the Active Members, present in person or by proxy at a meeting of the Club shall constitute a quorum. A majority vote of the Active Members present in person or by proxy at a constituted meeting shall be sufficient to carry a resolution or a motion.&lt;br /&gt;
===Section 6===&lt;br /&gt;
Candidates for election to the Board of Directors as a specific officer, representative or committee chairperson, shall stand for election as such and the candidate receiving a majority of the votes cast by Members entitled to vote thereon shall be so elected to such position. In the case of a tie, a second vote shall be taken. If a tie shall result from the second vote, a majority vote of the Board of Directors present in person at the meeting shall determine the winner and the first runner-up shall serve as an alternate in case the winner shall later resign or be removed during the term of office. Candidates for election to the Board of Directors at-large, shall all stand for election together. Directors for such at-large positions shall be elected by a plurality of the votes cast by Members entitled to vote thereon.&lt;br /&gt;
===Section 7===&lt;br /&gt;
A General Information Meeting may be held on a date and at such place and time as the board of Directors may determine. Written notice of a General Information Meeting must be given to all Active Members not less than ten (10) days nor more than sixty (60) days prior to any General Information Meeting. The purpose of the General Information Meeting may be to present the Budget for the Club for the ensuing year which the Board of Directors has approved and such other information as the Board may determine is appropriate for the general information of the membership. No quorum is required to constitute a General Information Meeting and no action may be taken thereat on a resolution, motion or any other matter.&lt;br /&gt;
===Section 8===&lt;br /&gt;
The Board of Directors may from time to time, adopt and prescribe reasonable procedures regarding the nomination and election of candidates to the Board of Directors, the submission of any matter to the vote of the membership, and the conducting of all Meetings of the Club. Roberts Rules of Order will prevail at all Meetings of the Club.&lt;br /&gt;
==ARTICLE IX - COMMITTEES==&lt;br /&gt;
===Section 1===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The standing committees shall be Buildings and Grounds, Social, Membership, Concessions and Swim Team.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The duties and powers assigned in these By-Laws to the standing committees shall be subject to the authority and modification of the Board of Directors. No Committee shall expend funds without prior appropriation by the Board of Directors.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 2===&lt;br /&gt;
The Buildings and Grounds Committee shall exercise supervision over the Pool/Buildings and Grounds; shall attend to the improvement and maintenance of the Pool/Buildings and Grounds and its operating equipment; shall have the authority thereover; and shall see that the rules and regulations of the Club relating to the Pool/ Buildings and Grounds are enforced.&lt;br /&gt;
===Section 3===&lt;br /&gt;
The Social Committee shall plan and supervise all parties and social functions for the Club.&lt;br /&gt;
===Section 4===&lt;br /&gt;
The Membership Committee shall exercise supervision over the inquiries, applications, approval, admittance and termination of all memberships in the Club; shall adopt and prescribe such procedures, as it deems appropriate for the orderly operation thereof; and shall collect all monies from new Members and remit the same to the Club.&lt;br /&gt;
===Section 5===&lt;br /&gt;
The Concessions Committee shall exercise supervision over the operation of the Concession area; shall have authority thereover; and shall procure the needed supplies and concessions.&lt;br /&gt;
===Section 6===&lt;br /&gt;
Such temporary committees as deemed necessary may be appointed by the Board of Directors and they shall terminate when the purpose of their formation has been fulfilled.&lt;br /&gt;
==ARTICLE X - INDEMNIFICATION: MISCELLANEOUS==&lt;br /&gt;
===Section 1===&lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Unless otherwise provided by law, the Club shall indemnify a person who was or is a party or is threatened to be made a party to a threatened, pending or completed action, suit, or proceeding, whether civil, criminal, administrative, or investigative and whether formal or informal, other than an action by or in the right of the Club, by reason of the fact that he or she is or was a director, officer, or employee of the Club, or is or was serving at the request of the Club as a director, officer, partner, trustee, employee, or agent of another foreign or domestic corporation, partnership, joint Venture, trust, or other enterprise, whether for profit or not, including attorneys&#039; fees, judgments, penalties, fines, and amounts paid in settlement actually and reasonably incurred by the person in connection with the action, suit or proceeding, if the person acted in good faith and in a manner the person reasonably believed to be in or not opposed to the best interests of the Club or its Members, and with respect to a criminal action or proceeding, if the person had no reasonable cause to believe his or her conduct was unlawful. The termination of any action, suit, or proceeding by judgment, order, settlement, conviction, or upon a plea of nolo contendere or its equivalent, does not, of itself, create a presumption that the person did not act in good faith and in a manner which he or she reasonably believed to be or not opposed to the best interests of the Club or its&lt;br /&gt;
Members, and with respect to a criminal action or proceeding, had reasonable cause to believe that his or her conduct was unlawful.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Unless otherwise provided by law, the Club shall indemnify any person who was or is a party to or is threatened to be made a party to a threatened, pending, or completed action or suit by or in the right of the Club to procure a judgment in its favor or by reason of the fact that he or she is or was a director, officer, or employee of the Club, or is or was serving at the request of the Club as a director, officer, partner, trustee, employee, or agent of another foreign or domestic corporation, partnership, joint venture, trust, or other enterprise, whether for profit or not, against expenses, including attorneys&#039; fees, and amounts paid in settlement actually and reasonably incurred by the person in connection with the action or suit, if the person acted in good faith and in a manner the person reasonably believed to be in or not opposed to the best interests of the Club or its Members. However, indemnification shall not be made for a claim, issue, or matter in which the person has been found liable to the Club unless and only to the&lt;br /&gt;
extent that the court in which the action or suit was brought has determined upon application that despite the adjudication of liability, but in view of all circumstances of the case, the person is fairly and reasonably entitled to indemnification for expenses which the court considers proper.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
===Section 2===&lt;br /&gt;
These By-Laws may be amended by a vote of the Active Members at any Meeting of the Club.&lt;br /&gt;
===Section 3===&lt;br /&gt;
Notwithstanding any provisions of these By-Laws to the contrary, no part of the net earnings of this club shall inure to the benefit of any member. An Active or Associate Member may be given consideration if he or she has proper background, training, thorough knowledge and applies for such position(s): (1) Fitness Instructor; (2) Diving Instructor; (3) Tennis Instructor; (4) Swim Coach, (5) Lifeguard or (6) Concession worker. Said position shall not be filled by a Board Member in his/her current term. Each position is considered “Contract” not “Ongoing”. Each position will be reconsidered on an annual basis.&lt;br /&gt;
&lt;br /&gt;
==Revision History==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Section&lt;br /&gt;
!Comment&lt;br /&gt;
|Article &lt;br /&gt;
|-&lt;br /&gt;
|January 2024&lt;br /&gt;
|Article VII, Section 1, g&lt;br /&gt;
|A delayed update to the bylaws to reflect the increased capital fee from $100 to $150 per an August 15th, 2023 vote by General Membership.&lt;br /&gt;
|-&lt;br /&gt;
|February 2023&lt;br /&gt;
|Article VII Section 1&lt;br /&gt;
|Increased annual dues from $550 to $585 (+6.3%) per a February 13th, 2023 board vote.&lt;br /&gt;
|-&lt;br /&gt;
|August 2022&lt;br /&gt;
|Article IV Section 1&lt;br /&gt;
|Added a Vice Treasurer position by vote of General Membership on August 16, 2022.&lt;br /&gt;
|-&lt;br /&gt;
|September 2022&lt;br /&gt;
|Article VII Section 1&lt;br /&gt;
|A delayed update to the bylaws to identify an increase in the annual dues from $525 to $550 (+4.8%) per a January 10th, 2022 board vote.&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=4|August 2020&lt;br /&gt;
|Article III Section 2&lt;br /&gt;
|Changed swim team coordinator terms (alignment for the lost 2020 season) per approval by the board and members at the 2020 annual meeting.&lt;br /&gt;
|-&lt;br /&gt;
|Article VI Section 1&lt;br /&gt;
|Increased the number of member bonds from 330 to 340 per approval by the board and members at the 2020 annual meeting.&lt;br /&gt;
|-&lt;br /&gt;
|Article VII Section 1, g&lt;br /&gt;
|Increased the capital fee from $75 to $100 per approval by the board and members at the 2020 annual meeting.&lt;br /&gt;
|-&lt;br /&gt;
|Article VII Section 1, h (added)&lt;br /&gt;
|Added the Capital Recovery fee of $100 per approval by the board and members at the 2020 annual meeting.&lt;br /&gt;
|-&lt;br /&gt;
|August 2020&lt;br /&gt;
|&lt;br /&gt;
|Document Transferred to Wiki&lt;br /&gt;
|-&lt;br /&gt;
|August 2019&lt;br /&gt;
|Article VI Section 2&amp;lt;br/&amp;gt;Article VII Section 10&lt;br /&gt;
|General Member Approval Vote&lt;br /&gt;
|-&lt;br /&gt;
|June 2018&lt;br /&gt;
|Article III, Section 2&amp;lt;br/&amp;gt;Article IV, Section 11&amp;lt;br/&amp;gt;Article VI, Section 2&amp;lt;br/&amp;gt;Article VII, Section 1(a), Section 1(e), Section 1(f), Section 8&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Feb 2017&lt;br /&gt;
|Article VII, Section 1(a)&lt;br /&gt;
|Amended Membership Dues fee per Board Member Vote&lt;br /&gt;
|-&lt;br /&gt;
|Sep 2016&lt;br /&gt;
|Article VI, Section 4&lt;br /&gt;
|Amended per Aug 2016 General Member Approval Vote&lt;br /&gt;
|-&lt;br /&gt;
|Feb 2016&lt;br /&gt;
|Article X, Section 3&lt;br /&gt;
|Amended per Aug 2015 General Member Approval Vote&lt;br /&gt;
|-&lt;br /&gt;
|Aug 2012&lt;br /&gt;
|&lt;br /&gt;
|Document Amended and Approved&lt;br /&gt;
|-&lt;br /&gt;
|Aug 2011&lt;br /&gt;
|&lt;br /&gt;
|Document Amended and Approved&lt;br /&gt;
|-&lt;br /&gt;
|Sep 2004&lt;br /&gt;
|&lt;br /&gt;
|Entire Document Scanned and Re-Formatted into Word&lt;br /&gt;
|-&lt;br /&gt;
|July 2000&lt;br /&gt;
|&lt;br /&gt;
|Entire Document Revised&lt;br /&gt;
|-&lt;br /&gt;
|Nov 6, 1991&lt;br /&gt;
|&lt;br /&gt;
|Entire Document Developed By-Laws Document&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:If/doc&amp;diff=1746</id>
		<title>Template:If/doc</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:If/doc&amp;diff=1746"/>
		<updated>2024-01-05T17:26:41Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Documentation subpage}}&lt;br /&gt;
With this template the [[Help:parser function|parser functions]] with names starting with &amp;quot;#if&amp;quot; can be used in a way such that they do not [[m:Help:Newlines_and_spaces#Trimming_on_expansion|strip spaces and newlines]] from the &amp;quot;then&amp;quot; and &amp;quot;else&amp;quot; part. Spaces still do not affect the outcome of the condition. Parameter 1 selects the if-type as &amp;quot;eq&amp;quot;, &amp;quot;expr&amp;quot;, &amp;quot;exist&amp;quot; or &amp;quot;error&amp;quot; (for #iferror), or empty &amp;quot;||&amp;quot; for a simple if-there (for #if). The template can be repeatedly nested 6 or 7 levels, one inside the other, because the outer-most is completed before running either the then/else inner levels.&lt;br /&gt;
&lt;br /&gt;
This template can be substituted, when the expression or comparison will not change. Functionally, a lead-space character is stored, internally, as a simple blank character. Note, in many cases a null nowiki tag (&amp;quot;&amp;amp;lt;nowiki/&amp;gt;&amp;quot;) could be used, without [[Template:If]], to allow a lead-space (such as &amp;quot;&amp;amp;lt;nowiki/&amp;gt;&amp;amp;nbsp;xx&amp;quot;) anywhere, but the internal storage puts a 43-character marker for &amp;quot;&amp;amp;lt;nowiki/&amp;gt;&amp;quot; in string length. However, there is no extra expansion depth for a nowiki-tag, such as in trailing space, &amp;quot;zz&amp;amp;nbsp;&amp;amp;lt;nowiki/&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
&#039;&#039;&#039;Where p is implemented in affirmation of the statement and q is implemented in negation of the statement&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;{{if||x| p | q }}&amp;lt;/nowiki&amp;gt; gives &amp;quot;{{if||x| p | q }}&amp;quot;. Notice the &#039;&#039;pair&#039;&#039; of vertical bars surrounding the empty first parameter.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;{{if|expr|2&amp;lt;3| p | q }}&amp;lt;/nowiki&amp;gt; gives &amp;quot; p &amp;quot;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;{{if|eq| u |u| p | q }}&amp;lt;/nowiki&amp;gt; gives &amp;quot;{{if|eq| u |u| p | q }}&amp;quot;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;{{if|exist| Help:Link | p | q }}&amp;lt;/nowiki&amp;gt; gives &amp;quot;{{if|exist| Help:Link | p | q }}&amp;quot;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;{{if|error|{{#expr:x}}| p | q }}&amp;lt;/nowiki&amp;gt; gives &amp;quot;{{if|error|{{#expr:x}}| p | q }}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Compare:&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;{{#if:x| p | q }}&amp;lt;/nowiki&amp;gt; gives &amp;quot;{{#if:x| p | q }}&amp;quot;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;{{#ifexpr:2&amp;lt;3| p | q }}&amp;lt;/nowiki&amp;gt; gives &amp;quot;{{#ifexpr:2&amp;lt;3| p | q }}&amp;quot;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;{{#ifeq: u |u| p | q }}&amp;lt;/nowiki&amp;gt; gives &amp;quot;{{#ifeq: u |u| p | q }}&amp;quot;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;{{#ifexist: Help:Link | p | q }}&amp;lt;/nowiki&amp;gt; gives &amp;quot;{{#ifexist: Help:Link | p | q }}&amp;quot;&lt;br /&gt;
*&amp;lt;nowiki&amp;gt;{{#iferror:{{#expr:x}}| p | q }}&amp;lt;/nowiki&amp;gt; gives &amp;quot;{{#iferror:{{#expr:x}}| p | q }}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For example, with a template named &#039;&#039;Template:Template name&#039;&#039; containing the code &amp;lt;nowiki&amp;gt;{{#ifeq: {{{parameter}}} |u| p | q }}&amp;lt;/nowiki&amp;gt;, entering the code &amp;lt;nowiki&amp;gt;{{{Template name|parameter=u}}}&amp;lt;/nowiki&amp;gt; into an article gives &amp;quot;p&amp;quot;, but &amp;lt;nowiki&amp;gt;{{{Template name|parameter=v}}}&amp;lt;/nowiki&amp;gt; gives &amp;quot;q&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The text of either the then-clause or else-clause is only processed and expanded when triggered. Hence, any templates in use are only expanded once the then-clause or else-clause is matched, otherwise they are skipped as merely paired braces, &amp;quot;{{((}}&amp;quot; with &amp;quot;{{))}}&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Indentation:&#039;&#039;&#039; If indenting the markup, care must be taken to avoid extra newlines when indenting &amp;quot;}}&amp;quot; on the next line. An extra bar pipe &amp;quot;|&amp;quot; can be added after the else-clause to complete that text, and allow &amp;quot;}}&amp;quot; to then be placed anywhere without adding a newline into the else-clause. For example:&lt;br /&gt;
:::* &amp;lt;nowiki&amp;gt;{{if|{{{1|}}}&amp;lt;/nowiki&amp;gt;&amp;lt;br&amp;gt;&amp;amp;nbsp; &amp;amp;nbsp; |then found parameter 1|else no parameter 1| &amp;amp;larr; &#039;&#039;extra&#039;&#039; &amp;quot;|&amp;quot; &#039;&#039;ends else-clause&#039;&#039;&amp;lt;br&amp;gt;}}&lt;br /&gt;
When the else-clause is indented to the next line, a newline (CR/LF) is added:&lt;br /&gt;
:::* &amp;lt;nowiki&amp;gt;{{if|{{{1|}}}&amp;lt;/nowiki&amp;gt;&amp;lt;br&amp;gt;&amp;amp;nbsp; &amp;amp;nbsp; |then found parameter 1 &amp;amp;larr; &#039;&#039;extra newline here&#039;&#039;&amp;lt;br&amp;gt;&amp;amp;nbsp; &amp;amp;nbsp; |else noparameter 1|&amp;lt;br&amp;gt;}}&lt;br /&gt;
To indent the else-clause, split an [[HTML]]-form comment, as &amp;quot;&amp;amp;lt;!--&amp;quot; with next line as &amp;quot;--&amp;amp;gt;|else...&amp;quot;. Unless each then-clause and else-clause is carefully tested, to watch for extra newlines, then the results are likely to cause broken lines, with extra line breaks for each newline. For that reason, a global edit with simple search-and-replace of &amp;quot;&amp;lt;code&amp;gt;{#if:&amp;lt;/code&amp;gt;&amp;quot; to &amp;quot;&amp;lt;code&amp;gt;{if||&amp;lt;/code&amp;gt;&amp;quot; is likely to leave newline problems, wherever the original markup was wrapped to indent either the else-clause or &amp;quot;}}&amp;quot; of each if-structure. Indenting the then-clause is not a problem.&lt;br /&gt;
&lt;br /&gt;
==Performance considerations==&lt;br /&gt;
Because [[Template:If]] must prepare the parameters for &amp;lt;code&amp;gt;#if, #ifeq, #ifexpr,&amp;lt;/code&amp;gt; (etc.) there is a slight overhead when using it. It has been timed to run at speeds of 290 instances per second, so 29 uses would take only 0.1&amp;amp;nbsp;s, a tenth of a second to run, to make 29 comparisons. Each nested use adds 5 levels to the template expansion depth, so 7 nested if-templates would use 35 levels (5*7) of the [[m:Help:Expansion_depth|41-level limit]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Using P-if syntax:&#039;&#039;&#039; A similar if-structure can be coded without &#039;&#039;&#039;Template:If&#039;&#039;&#039;, by using the {P1} and {P2} templates in a &amp;quot;P-if&amp;quot; structure. [[Template:P1]] always returns parameter 1, and P2 returns the 2nd. So, a comparison of 4 versus 3 can be coded using P-if syntax form:&lt;br /&gt;
:: Example of &amp;lt;code&amp;gt;#ifexpr&amp;lt;/code&amp;gt;: &amp;lt;nowiki&amp;gt;&amp;quot;{{P{{#ifexpr: 4 &amp;gt; 3|1|2}}| then 4 greater| else 4 lower}}&amp;quot;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:: Result for &amp;lt;code&amp;gt;#ifexpr&amp;lt;/code&amp;gt;: &amp;amp;nbsp; &amp;quot;{{P{{#ifexpr: 4 &amp;gt; 3|1|2}}| then 4 greater| else 4 lower}}&amp;quot; &amp;amp;larr; &#039;&#039;the comparison invoked&#039;&#039; {&amp;lt;nowiki/&amp;gt;{P1}}.&lt;br /&gt;
The expansion depth of a P-if is only 4 levels deep, but nesting of the then-clause or else-clause might be more confusing than using nested levels of Template:if.&lt;br /&gt;
&lt;br /&gt;
:: Example of &amp;lt;code&amp;gt;#if&amp;lt;/code&amp;gt;: &amp;lt;nowiki&amp;gt;&amp;quot;{{P{{#if:{{{2|x}}}|1|2}}| then {2} set| else {2} empty}}&amp;quot;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:: Result for &amp;lt;code&amp;gt;#if&amp;lt;/code&amp;gt;: &amp;quot;{{P{{#if:{{{2|}}}|1|2}}| then {2} set| else {2} empty}}&amp;quot; &amp;amp;larr; &#039;&#039;the comparison invoked&#039;&#039; {&amp;lt;nowiki/&amp;gt;{P2}}.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[[m:Template:If]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;includeonly&amp;gt;&lt;br /&gt;
[[Category:Templates]]&lt;br /&gt;
&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:P1&amp;diff=1744</id>
		<title>Template:P1</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:P1&amp;diff=1744"/>
		<updated>2024-01-05T17:26:41Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{{1}}}&amp;lt;noinclude&amp;gt;{{doc}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:P2&amp;diff=1742</id>
		<title>Template:P2</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:P2&amp;diff=1742"/>
		<updated>2024-01-05T17:26:41Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{{2}}}&amp;lt;noinclude&amp;gt;{{doc|Template:P1/doc}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:Doc&amp;diff=1740</id>
		<title>Template:Doc</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:Doc&amp;diff=1740"/>
		<updated>2024-01-05T17:26:40Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT[[Template:Documentation]]&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:If&amp;diff=1738</id>
		<title>Template:If</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:If&amp;diff=1738"/>
		<updated>2024-01-05T17:26:40Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ safesubst:&amp;lt;noinclude/&amp;gt;p{{ safesubst:&amp;lt;noinclude/&amp;gt;#ifeq:{{{1}}}|eq|1|2}}|{{ safesubst:&amp;lt;noinclude/&amp;gt;p{{ safesubst:&amp;lt;noinclude/&amp;gt;#ifeq:{{{2}}}|{{{3}}}|1|2}}|{{{4|}}}|{{{5|}}}}}|{{ safesubst:&amp;lt;noinclude/&amp;gt;p{{ safesubst:&amp;lt;noinclude/&amp;gt;#if{{{1}}}:{{{2}}}|1|2}}|{{{3}}}|{{{4|}}}}}}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{doc}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Lua_banner/testcases&amp;diff=1736</id>
		<title>Module:Lua banner/testcases</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Lua_banner/testcases&amp;diff=1736"/>
		<updated>2024-01-05T17:23:49Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local mList = require(&#039;Module:List&#039;)&lt;br /&gt;
local mMessageBox = require(&#039;Module:Message box&#039;)&lt;br /&gt;
&lt;br /&gt;
local p = require(&#039;Module:ScribuntoUnit&#039;):new()&lt;br /&gt;
&lt;br /&gt;
local noWishConfig = {&lt;br /&gt;
	subpage_blacklist = {&lt;br /&gt;
		[&#039;doc&#039;] = true&lt;br /&gt;
	},&lt;br /&gt;
	allow_wishes = false,&lt;br /&gt;
	error_category = &#039;ERRCAT_TITLE&#039;,&lt;br /&gt;
	-- wish_category = nil, -- should not be accessed&lt;br /&gt;
	default_category = &#039;DEFCAT_TITLE&#039;,&lt;br /&gt;
	module_categories = {&lt;br /&gt;
		[&#039;String&#039;] = &#039;STRINGCAT_TITLE&#039;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
local withWishConfig = {&lt;br /&gt;
	subpage_blacklist = {&lt;br /&gt;
		[&#039;doc&#039;] = true&lt;br /&gt;
	},&lt;br /&gt;
	allow_wishes = true,&lt;br /&gt;
	-- error_category = nil, -- should not be accessed&lt;br /&gt;
	wish_category = &#039;WISHCAT_TITLE&#039;,&lt;br /&gt;
	default_category = &#039;DEFCAT_TITLE&#039;,&lt;br /&gt;
	module_categories = {&lt;br /&gt;
		[&#039;String&#039;] = &#039;STRINGCAT_TITLE&#039;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
local configMetatable = {&lt;br /&gt;
	__index = function(t, k) error(&amp;quot;Unexpected field &#039;&amp;quot; .. k .. &amp;quot;&#039; accessed.&amp;quot;) end&lt;br /&gt;
}&lt;br /&gt;
setmetatable(noWishConfig, configMetatable)&lt;br /&gt;
setmetatable(withWishConfig, configMetatable)&lt;br /&gt;
&lt;br /&gt;
-- Allow test runner to use both the Module:XXX itself and Module:XXX/sandbox with the same testcases&lt;br /&gt;
function p:module()&lt;br /&gt;
	return self.frame and self.frame.args and self.frame.args.module or &#039;Lua banner&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p:box(text)&lt;br /&gt;
	local boxArgs = {&lt;br /&gt;
		text = text,&lt;br /&gt;
		type = &#039;notice&#039;,&lt;br /&gt;
		small = true,&lt;br /&gt;
		image = &#039;[[File:Lua-logo-nolabel.svg|30px|alt=Lua logo|link=wikipedia:Wikipedia:Lua]]&#039;&lt;br /&gt;
	}&lt;br /&gt;
	return mMessageBox.main(&#039;mbox&#039;, boxArgs)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p:boxFromList(moduleLinks, withWishes)&lt;br /&gt;
	if #moduleLinks == 0 then&lt;br /&gt;
		if withWishes then&lt;br /&gt;
			return self:box(&#039;This template should use [[wikipedia:Wikipedia:Lua|Lua]]&#039;)&lt;br /&gt;
		else&lt;br /&gt;
			return self:box(&#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;Error: no modules specified&amp;lt;/strong&amp;gt;&#039;)&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return self:box(&#039;Uses [[wikipedia:Wikipedia:Lua|Lua]]:\n&#039; .. mList.makeList(&#039;bulleted&#039;, moduleLinks))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p:assertTCBoth(args, modules, titleObj, expected)&lt;br /&gt;
	local func = require(&#039;Module:&#039; .. p:module()).renderTrackingCategories&lt;br /&gt;
	self:assertEquals(func(args, modules, titleObj, noWishConfig), expected)&lt;br /&gt;
	self:assertEquals(func(args, modules, titleObj, withWishConfig), expected)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function ignoreStripMarkersExceptNoWiki(s)&lt;br /&gt;
	-- return mw.text.unstrip(s);&lt;br /&gt;
	return mw.text.killMarkers(mw.text.unstripNoWiki(s));&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p:assertEqualsIgnoreStripMarkers(a, b, ...)&lt;br /&gt;
	if (type(a) == &amp;quot;string&amp;quot;) then&lt;br /&gt;
		a = ignoreStripMarkersExceptNoWiki(a);&lt;br /&gt;
	end&lt;br /&gt;
	if (type(b) == &amp;quot;string&amp;quot;) then&lt;br /&gt;
		b = ignoreStripMarkersExceptNoWiki(b);&lt;br /&gt;
	end&lt;br /&gt;
	return self:assertEquals(a, b, ...);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p:testRenderBox()&lt;br /&gt;
	local func = require(&#039;Module:&#039; .. p:module()).renderBox&lt;br /&gt;
	self:assertEqualsIgnoreStripMarkers(func({}, noWishConfig), self:boxFromList{})&lt;br /&gt;
	self:assertEqualsIgnoreStripMarkers(func({}, withWishConfig), self:boxFromList({}, true))&lt;br /&gt;
	self:assertEqualsIgnoreStripMarkers(func({&#039;Module:Lua banner&#039;}, noWishConfig), self:boxFromList{&#039;[[:Module:Lua banner]]&#039;})&lt;br /&gt;
	self:assertEqualsIgnoreStripMarkers(func({&#039;Module:Lua banner&#039;}, withWishConfig), self:boxFromList{&#039;[[:Module:Lua banner]]&#039;})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p:testRenderTrackingCategories()&lt;br /&gt;
	local func = require(&#039;Module:&#039; .. p:module()).renderTrackingCategories&lt;br /&gt;
	local moduleTitle = mw.title.new(&#039;Module:Lua banner&#039;)&lt;br /&gt;
	local templateTitle = mw.title.new(&#039;Template:Lua&#039;)&lt;br /&gt;
	local templateDocTitle = mw.title.new(&#039;Template:Lua/doc&#039;)&lt;br /&gt;
	self:assertEquals(func({}, {}, moduleTitle, noWishConfig), &#039;[[Category:ERRCAT_TITLE]]&#039;)&lt;br /&gt;
	self:assertEquals(func({}, {}, moduleTitle, withWishConfig), &#039;&#039;)&lt;br /&gt;
	self:assertEquals(func({}, {}, templateTitle, noWishConfig), &#039;[[Category:ERRCAT_TITLE]][[Category:DEFCAT_TITLE]]&#039;)&lt;br /&gt;
	self:assertEquals(func({}, {}, templateTitle, withWishConfig), &#039;[[Category:WISHCAT_TITLE]]&#039;)&lt;br /&gt;
	self:assertEquals(func({}, {}, templateDocTitle, noWishConfig), &#039;[[Category:ERRCAT_TITLE]]&#039;)&lt;br /&gt;
	self:assertEquals(func({}, {}, templateDocTitle, withWishConfig), &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({}, {&#039;Module:Lua banner&#039;}, moduleTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({}, {&#039;Module:Lua banner&#039;}, templateTitle, &#039;[[Category:DEFCAT_TITLE]]&#039;)&lt;br /&gt;
	self:assertTCBoth({}, {&#039;Module:Lua banner&#039;}, templateDocTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({}, {&#039;Module:Lua banner&#039;, &#039;Module:String&#039;}, moduleTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({}, {&#039;Module:Lua banner&#039;, &#039;Module:String&#039;}, templateTitle, &#039;[[Category:DEFCAT_TITLE]]&#039;)&lt;br /&gt;
	self:assertTCBoth({}, {&#039;Module:Lua banner&#039;, &#039;Module:String&#039;}, templateDocTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({}, {&#039;Module:String&#039;, &#039;Module:Lua banner&#039;}, moduleTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({}, {&#039;Module:String&#039;, &#039;Module:Lua banner&#039;}, templateTitle, &#039;[[Category:STRINGCAT_TITLE]]&#039;)&lt;br /&gt;
	self:assertTCBoth({}, {&#039;Module:String&#039;, &#039;Module:Lua banner&#039;}, templateDocTitle, &#039;&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p:testRenderTrackingCategoriesWithNocat()&lt;br /&gt;
	local moduleTitle = mw.title.new(&#039;Module:Lua banner&#039;)&lt;br /&gt;
	local templateTitle = mw.title.new(&#039;Template:Lua&#039;)&lt;br /&gt;
	local templateDocTitle = mw.title.new(&#039;Template:Lua/doc&#039;)&lt;br /&gt;
	self:assertTCBoth({nocat=&#039;true&#039;}, {}, moduleTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({nocat=&#039;true&#039;}, {}, templateTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({nocat=&#039;true&#039;}, {}, templateDocTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({nocat=&#039;true&#039;}, {&#039;Module:Lua banner&#039;}, moduleTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({nocat=&#039;true&#039;}, {&#039;Module:Lua banner&#039;}, templateTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({nocat=&#039;true&#039;}, {&#039;Module:Lua banner&#039;}, templateDocTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({nocat=&#039;true&#039;}, {&#039;Module:Lua banner&#039;, &#039;Module:String&#039;}, moduleTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({nocat=&#039;true&#039;}, {&#039;Module:Lua banner&#039;, &#039;Module:String&#039;}, templateTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({nocat=&#039;true&#039;}, {&#039;Module:Lua banner&#039;, &#039;Module:String&#039;}, templateDocTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({nocat=&#039;true&#039;}, {&#039;Module:String&#039;, &#039;Module:Lua banner&#039;}, moduleTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({nocat=&#039;true&#039;}, {&#039;Module:String&#039;, &#039;Module:Lua banner&#039;}, templateTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({nocat=&#039;true&#039;}, {&#039;Module:String&#039;, &#039;Module:Lua banner&#039;}, templateDocTitle, &#039;&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p:testRenderTrackingCategoriesWithCategory()&lt;br /&gt;
	local func = require(&#039;Module:&#039; .. p:module()).renderTrackingCategories&lt;br /&gt;
	local moduleTitle = mw.title.new(&#039;Module:Lua banner&#039;)&lt;br /&gt;
	local templateTitle = mw.title.new(&#039;Template:Lua&#039;)&lt;br /&gt;
	local templateDocTitle = mw.title.new(&#039;Template:Lua/doc&#039;)&lt;br /&gt;
	self:assertEquals(func({category=&#039;catname&#039;}, {}, moduleTitle, noWishConfig), &#039;[[Category:ERRCAT_TITLE]]&#039;)&lt;br /&gt;
	self:assertEquals(func({category=&#039;catname&#039;}, {}, moduleTitle, withWishConfig), &#039;&#039;)&lt;br /&gt;
	self:assertEquals(func({category=&#039;catname&#039;}, {}, templateTitle, noWishConfig), &#039;[[Category:ERRCAT_TITLE]][[Category:catname]]&#039;)&lt;br /&gt;
	self:assertEquals(func({category=&#039;catname&#039;}, {}, templateTitle, withWishConfig), &#039;[[Category:catname]]&#039;)&lt;br /&gt;
	self:assertEquals(func({category=&#039;catname&#039;}, {}, templateDocTitle, noWishConfig), &#039;[[Category:ERRCAT_TITLE]]&#039;)&lt;br /&gt;
	self:assertEquals(func({category=&#039;catname&#039;}, {}, templateDocTitle, withWishConfig), &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({category=&#039;catname&#039;}, {&#039;Module:Lua banner&#039;}, moduleTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({category=&#039;catname&#039;}, {&#039;Module:Lua banner&#039;}, templateTitle, &#039;[[Category:catname]]&#039;)&lt;br /&gt;
	self:assertTCBoth({category=&#039;catname&#039;}, {&#039;Module:Lua banner&#039;}, templateDocTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({category=&#039;catname&#039;}, {&#039;Module:Lua banner&#039;, &#039;Module:String&#039;}, moduleTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({category=&#039;catname&#039;}, {&#039;Module:Lua banner&#039;, &#039;Module:String&#039;}, templateTitle, &#039;[[Category:catname]]&#039;)&lt;br /&gt;
	self:assertTCBoth({category=&#039;catname&#039;}, {&#039;Module:Lua banner&#039;, &#039;Module:String&#039;}, templateDocTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({category=&#039;catname&#039;}, {&#039;Module:String&#039;, &#039;Module:Lua banner&#039;}, moduleTitle, &#039;&#039;)&lt;br /&gt;
	self:assertTCBoth({category=&#039;catname&#039;}, {&#039;Module:String&#039;, &#039;Module:Lua banner&#039;}, templateTitle, &#039;[[Category:catname]]&#039;)&lt;br /&gt;
	self:assertTCBoth({category=&#039;catname&#039;}, {&#039;Module:String&#039;, &#039;Module:Lua banner&#039;}, templateDocTitle, &#039;&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p:testMain()&lt;br /&gt;
	local func = require(&#039;Module:&#039; .. p:module())._main&lt;br /&gt;
	self:assertEqualsIgnoreStripMarkers(func({}, noWishConfig), self:boxFromList{} .. &#039;[[Category:ERRCAT_TITLE]]&#039;)&lt;br /&gt;
	self:assertEqualsIgnoreStripMarkers(func({}, withWishConfig), self:boxFromList({}, true))&lt;br /&gt;
	self:assertEqualsIgnoreStripMarkers(func({nil}, noWishConfig), self:boxFromList{} .. &#039;[[Category:ERRCAT_TITLE]]&#039;)&lt;br /&gt;
	self:assertEqualsIgnoreStripMarkers(func({nil}, withWishConfig), self:boxFromList({}, true))&lt;br /&gt;
	self:assertEqualsIgnoreStripMarkers(func({&#039;Module:Lua banner&#039;}, noWishConfig), self:boxFromList{&#039;[[:Module:Lua banner]]&#039;})&lt;br /&gt;
	self:assertEqualsIgnoreStripMarkers(func({&#039;Module:Lua banner&#039;}, withWishConfig), self:boxFromList{&#039;[[:Module:Lua banner]]&#039;})&lt;br /&gt;
	self:assertEqualsIgnoreStripMarkers(func({nil, &#039;Module:Lua banner&#039;}, noWishConfig), self:boxFromList{&#039;[[:Module:Lua banner]]&#039;})&lt;br /&gt;
	self:assertEqualsIgnoreStripMarkers(func({nil, &#039;Module:Lua banner&#039;}, withWishConfig), self:boxFromList{&#039;[[:Module:Lua banner]]&#039;})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Lua_banner/sandbox&amp;diff=1734</id>
		<title>Module:Lua banner/sandbox</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Lua_banner/sandbox&amp;diff=1734"/>
		<updated>2024-01-05T17:23:49Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module implements the {{lua}} template.&lt;br /&gt;
&lt;br /&gt;
local yesno = require(&#039;Module:Yesno&#039;)&lt;br /&gt;
local mList = require(&#039;Module:List&#039;)&lt;br /&gt;
local mTableTools = require(&#039;Module:TableTools&#039;)&lt;br /&gt;
local mMessageBox = require(&#039;Module:Message box&#039;)&lt;br /&gt;
local TNT = require(&#039;Module:TNT&#039;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local function format(msg)&lt;br /&gt;
	return TNT.format(&#039;I18n/Lua banner&#039;, msg)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getConfig()&lt;br /&gt;
	return mw.loadData(&#039;Module:Lua banner/config/sandbox&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local origArgs = frame:getParent().args&lt;br /&gt;
	local args = {}&lt;br /&gt;
	for k, v in pairs(origArgs) do&lt;br /&gt;
		v = v:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
		if v ~= &#039;&#039; then&lt;br /&gt;
			args[k] = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return p._main(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(args, cfg)&lt;br /&gt;
	local modules = mTableTools.compressSparseArray(args)&lt;br /&gt;
	local box = p.renderBox(modules, cfg)&lt;br /&gt;
	local trackingCategories = p.renderTrackingCategories(args, modules, nil, cfg)&lt;br /&gt;
	return box .. trackingCategories&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderBox(modules, cfg)&lt;br /&gt;
	local boxArgs = {}&lt;br /&gt;
	if #modules &amp;lt; 1 then&lt;br /&gt;
		cfg = cfg or getConfig()&lt;br /&gt;
		if cfg[&#039;allow_wishes&#039;] then&lt;br /&gt;
			boxArgs.text = format(&#039;wishtext&#039;)&lt;br /&gt;
		else&lt;br /&gt;
			boxArgs.text = string.format(&#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;%s&amp;lt;/strong&amp;gt;&#039;, format(&#039;error_emptylist&#039;))&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		local moduleLinks = {}&lt;br /&gt;
		for i, module in ipairs(modules) do&lt;br /&gt;
			moduleLinks[i] = string.format(&#039;[[:%s]]&#039;, module)&lt;br /&gt;
		end&lt;br /&gt;
		local moduleList = mList.makeList(&#039;bulleted&#039;, moduleLinks)&lt;br /&gt;
		boxArgs.text = format(&#039;header&#039;) .. &#039;\n&#039; .. moduleList&lt;br /&gt;
	end&lt;br /&gt;
	boxArgs.type = &#039;notice&#039;&lt;br /&gt;
	boxArgs.small = true&lt;br /&gt;
	boxArgs.image = string.format(&lt;br /&gt;
		&#039;[[File:Lua-logo-nolabel.svg|30px|alt=%s|link=%s]]&#039;,&lt;br /&gt;
		format(&#039;logo_alt&#039;),&lt;br /&gt;
		format(&#039;logo_link&#039;)&lt;br /&gt;
	)&lt;br /&gt;
	return mMessageBox.main(&#039;mbox&#039;, boxArgs)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderTrackingCategories(args, modules, titleObj, cfg)&lt;br /&gt;
	if yesno(args.nocat) then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	cfg = cfg or getConfig()&lt;br /&gt;
	&lt;br /&gt;
	local cats = {}&lt;br /&gt;
	&lt;br /&gt;
	-- Error category&lt;br /&gt;
	if #modules &amp;lt; 1 and not cfg[&#039;allow_wishes&#039;] and cfg[&#039;error_category&#039;] then&lt;br /&gt;
		cats[#cats + 1] = cfg[&#039;error_category&#039;]&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Lua templates category&lt;br /&gt;
	titleObj = titleObj or mw.title.getCurrentTitle()&lt;br /&gt;
	if titleObj.namespace == 10 &lt;br /&gt;
		and not cfg[&#039;subpage_blacklist&#039;][titleObj.subpageText]&lt;br /&gt;
	then&lt;br /&gt;
		local category = args.category&lt;br /&gt;
		if not category then&lt;br /&gt;
			local pagename = modules[1] and mw.title.new(modules[1])&lt;br /&gt;
			category = pagename and cfg[&#039;module_categories&#039;][pagename.text]&lt;br /&gt;
			if not category then&lt;br /&gt;
				if cfg[&#039;allow_wishes&#039;] and #modules &amp;lt; 1 then&lt;br /&gt;
					category = cfg[&#039;wish_category&#039;]&lt;br /&gt;
				else&lt;br /&gt;
					category = cfg[&#039;default_category&#039;]&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if category then&lt;br /&gt;
			cats[#cats + 1] = category&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	for i, cat in ipairs(cats) do&lt;br /&gt;
		cats[i] = string.format(&#039;[[Category:%s]]&#039;, cat)&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat(cats)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Lua_banner/doc&amp;diff=1732</id>
		<title>Module:Lua banner/doc</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Lua_banner/doc&amp;diff=1732"/>
		<updated>2024-01-05T17:23:48Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Shared Template Warning|Module:Lua banner|Lua banner}}&lt;br /&gt;
&amp;lt;!-- Add categories where indicated at the bottom of this page and interwikis at Wikidata --&amp;gt;&lt;br /&gt;
{{Lua|Module:Lua banner/config|Module:Yesno|Module:List|Module:TableTools|Module:Message box}}&lt;br /&gt;
{{Uses TNT|Lua banner}}&lt;br /&gt;
{{Module rating|release}}&lt;br /&gt;
&lt;br /&gt;
This module implements the {{tlx|Lua}} template.&lt;br /&gt;
&lt;br /&gt;
== Module Quality ==&lt;br /&gt;
{{ModuleQuality}}&lt;br /&gt;
&lt;br /&gt;
== Usage from wikitext ==&lt;br /&gt;
&lt;br /&gt;
This module cannot be used directly from wikitext. It can only be used through the {{tlx|Lua}} template. Please see the template page for documentation.&lt;br /&gt;
&lt;br /&gt;
== Usage from Lua modules ==&lt;br /&gt;
&lt;br /&gt;
To use this module from other Lua modules, first load the module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local mLuaBanner = require(&#039;Module:Lua banner&#039;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then generate a side box using the _main function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
mLuaBanner._main(args)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;var&amp;gt;args&amp;lt;/var&amp;gt; variable should be a table containing the arguments to pass to the module. To see the different arguments that can be specified and how they affect the module output, please refer to the {{tlx|Lua}} template documentation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;includeonly&amp;gt;{{Sandbox other||&lt;br /&gt;
&amp;lt;!-- Categories below this line; interwikis at Wikidata --&amp;gt;&lt;br /&gt;
[[Category:Lua-based templates{{#translation:}}| ]]&lt;br /&gt;
}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Module documentation pages{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:ScribuntoUnit/config&amp;diff=1730</id>
		<title>Module:ScribuntoUnit/config</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:ScribuntoUnit/config&amp;diff=1730"/>
		<updated>2024-01-05T17:23:48Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- The cfg table, created by this module, contains all localisable strings and&lt;br /&gt;
-- configuration, to make it easier to port this module to another wiki.&lt;br /&gt;
local cfg = {} -- Do not edit this line.&lt;br /&gt;
&lt;br /&gt;
-- The successIndicator and failureIndicator are in the first column of the&lt;br /&gt;
-- wikitable produced as output and indicate whether the test passed.  These two&lt;br /&gt;
-- strings are preprocessed by frame.preprocess.&lt;br /&gt;
-- successIndicator: if the test passes&lt;br /&gt;
-- failureIndicator: if the test fails&lt;br /&gt;
cfg.successIndicator = &amp;quot;{{tick}}&amp;quot;&lt;br /&gt;
cfg.failureIndicator = &amp;quot;{{cross}}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- The names of the columns Name, Expected and Actual (the other three columns,&lt;br /&gt;
-- in this order)&lt;br /&gt;
cfg.nameString = &amp;quot;Name&amp;quot;&lt;br /&gt;
cfg.expectedString = &amp;quot;Expected&amp;quot;&lt;br /&gt;
cfg.actualString = &amp;quot;Actual&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- The string at the top used to indicate all tests passed.&lt;br /&gt;
cfg.successSummary = &amp;quot;All tests passed.&amp;quot;&lt;br /&gt;
-- The string at the top used to indicate one or more tests failed. $1 is&lt;br /&gt;
-- replaced by the number of tests that failed.  This string is preprocessed by&lt;br /&gt;
-- frame.preprocess.&lt;br /&gt;
cfg.failureSummary = &amp;quot;&#039;&#039;&#039;$1 {{PLURAL:$1|test|tests}} failed&#039;&#039;&#039;.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- Format string for a short display of the tests in displayResultsAsShort.&lt;br /&gt;
-- This format string is passed directly to string.format.&lt;br /&gt;
cfg.shortResultsFormat = &amp;quot;success: %d, error: %d, skipped: %d&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- Category added to pages that fail one or more tests. Set to nil to disable&lt;br /&gt;
-- categorisation of pages that fail one or more tests.&lt;br /&gt;
cfg.failureCategory = &amp;quot;[[Category:ScribuntoUnit failed tests]]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- Finally, return the configuration table.&lt;br /&gt;
return cfg -- Do not edit this line.&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:ScribuntoUnit&amp;diff=1728</id>
		<title>Module:ScribuntoUnit</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:ScribuntoUnit&amp;diff=1728"/>
		<updated>2024-01-05T17:23:48Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-------------------------------------------------------------------------------&lt;br /&gt;
-- Unit tests for Scribunto.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
require(&#039;strict&#039;)&lt;br /&gt;
&lt;br /&gt;
local DebugHelper = {}&lt;br /&gt;
local ScribuntoUnit = {}&lt;br /&gt;
&lt;br /&gt;
-- The cfg table contains all localisable strings and configuration, to make it&lt;br /&gt;
-- easier to port this module to another wiki.&lt;br /&gt;
local cfg = mw.loadData(&#039;Module:ScribuntoUnit/config&#039;)&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Concatenates keys and values, ideal for displaying a template or parser function argument table.&lt;br /&gt;
-- @param keySeparator glue between key and value (defaults to &amp;quot; = &amp;quot;)&lt;br /&gt;
-- @param separator glue between different key-value pairs (defaults to &amp;quot;, &amp;quot;)&lt;br /&gt;
-- @example concatWithKeys({a = 1, b = 2, c = 3}, &#039; =&amp;gt; &#039;, &#039;, &#039;) =&amp;gt; &amp;quot;a =&amp;gt; 1, b =&amp;gt; 2, c =&amp;gt; 3&amp;quot;&lt;br /&gt;
-- &lt;br /&gt;
function DebugHelper.concatWithKeys(table, keySeparator, separator)&lt;br /&gt;
    keySeparator = keySeparator or &#039; = &#039;&lt;br /&gt;
    separator = separator or &#039;, &#039;&lt;br /&gt;
    local concatted = &#039;&#039;&lt;br /&gt;
    local i = 1&lt;br /&gt;
    local first = true&lt;br /&gt;
    local unnamedArguments = true&lt;br /&gt;
    for k, v in pairs(table) do&lt;br /&gt;
        if first then&lt;br /&gt;
            first = false&lt;br /&gt;
        else&lt;br /&gt;
            concatted = concatted .. separator&lt;br /&gt;
        end&lt;br /&gt;
        if k == i and unnamedArguments then&lt;br /&gt;
            i = i + 1&lt;br /&gt;
            concatted = concatted .. tostring(v)&lt;br /&gt;
        else&lt;br /&gt;
            unnamedArguments = false&lt;br /&gt;
            concatted = concatted .. tostring(k) .. keySeparator .. tostring(v)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return concatted&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Compares two tables recursively (non-table values are handled correctly as well).&lt;br /&gt;
-- @param ignoreMetatable if false, t1.__eq is used for the comparison&lt;br /&gt;
-- &lt;br /&gt;
function DebugHelper.deepCompare(t1, t2, ignoreMetatable)&lt;br /&gt;
    local type1 = type(t1)&lt;br /&gt;
    local type2 = type(t2)&lt;br /&gt;
&lt;br /&gt;
    if type1 ~= type2 then &lt;br /&gt;
        return false &lt;br /&gt;
    end&lt;br /&gt;
    if type1 ~= &#039;table&#039; then &lt;br /&gt;
        return t1 == t2 &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local metatable = getmetatable(t1)&lt;br /&gt;
    if not ignoreMetatable and metatable and metatable.__eq then &lt;br /&gt;
        return t1 == t2 &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for k1, v1 in pairs(t1) do&lt;br /&gt;
        local v2 = t2[k1]&lt;br /&gt;
        if v2 == nil or not DebugHelper.deepCompare(v1, v2) then &lt;br /&gt;
            return false &lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    for k2, v2 in pairs(t2) do&lt;br /&gt;
        if t1[k2] == nil then &lt;br /&gt;
            return false &lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Raises an error with stack information&lt;br /&gt;
-- @param details a table with error details&lt;br /&gt;
--        - should have a &#039;text&#039; key which is the error message to display&lt;br /&gt;
--        - a &#039;trace&#039; key will be added with the stack data&lt;br /&gt;
--        - and a &#039;source&#039; key with file/line number&lt;br /&gt;
--        - a metatable will be added for error handling&lt;br /&gt;
-- &lt;br /&gt;
function DebugHelper.raise(details, level)&lt;br /&gt;
    level = (level or 1) + 1&lt;br /&gt;
    details.trace = debug.traceback(&#039;&#039;, level)&lt;br /&gt;
    details.source = string.match(details.trace, &#039;^%s*stack traceback:%s*(%S*: )&#039;)&lt;br /&gt;
&lt;br /&gt;
--    setmetatable(details, {&lt;br /&gt;
--        __tostring: function() return details.text end&lt;br /&gt;
--    })&lt;br /&gt;
&lt;br /&gt;
    error(details, level)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- when used in a test, that test gets ignored, and the skipped count increases by one.&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:markTestSkipped()&lt;br /&gt;
    DebugHelper.raise({ScribuntoUnit = true, skipped = true}, 3)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that the input is true&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:assertTrue(actual, message)&lt;br /&gt;
    if not actual then&lt;br /&gt;
        DebugHelper.raise({ScribuntoUnit = true, text = string.format(&amp;quot;Failed to assert that %s is true&amp;quot;, tostring(actual)), message = message}, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that the input is false&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:assertFalse(actual, message)&lt;br /&gt;
    if actual then&lt;br /&gt;
        DebugHelper.raise({ScribuntoUnit = true, text = string.format(&amp;quot;Failed to assert that %s is false&amp;quot;, tostring(actual)), message = message}, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks an input string contains the expected string&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @param plain search is made with a plain string instead of a ustring pattern&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:assertStringContains(pattern, s, plain, message)&lt;br /&gt;
	if type(pattern) ~= &#039;string&#039; then&lt;br /&gt;
		DebugHelper.raise({&lt;br /&gt;
			ScribuntoUnit = true,&lt;br /&gt;
			text = mw.ustring.format(&amp;quot;Pattern type error (expected string, got %s)&amp;quot;, type(pattern)),&lt;br /&gt;
			message = message&lt;br /&gt;
		}, 2)&lt;br /&gt;
	end&lt;br /&gt;
	if type(s) ~= &#039;string&#039; then&lt;br /&gt;
		DebugHelper.raise({&lt;br /&gt;
			ScribuntoUnit = true,&lt;br /&gt;
			text = mw.ustring.format(&amp;quot;String type error (expected string, got %s)&amp;quot;, type(s)),&lt;br /&gt;
			message = message&lt;br /&gt;
		}, 2)&lt;br /&gt;
	end&lt;br /&gt;
	if not mw.ustring.find(s, pattern, nil, plain) then&lt;br /&gt;
		DebugHelper.raise({&lt;br /&gt;
			ScribuntoUnit = true,&lt;br /&gt;
			text = mw.ustring.format(&#039;Failed to find %s &amp;quot;%s&amp;quot; in string &amp;quot;%s&amp;quot;&#039;, plain and &amp;quot;plain string&amp;quot; or &amp;quot;pattern&amp;quot;, pattern, s),&lt;br /&gt;
			message = message&lt;br /&gt;
		}, 2)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks an input string doesn&#039;t contain the expected string&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @param plain search is made with a plain string instead of a ustring pattern&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:assertNotStringContains(pattern, s, plain, message)&lt;br /&gt;
	if type(pattern) ~= &#039;string&#039; then&lt;br /&gt;
		DebugHelper.raise({&lt;br /&gt;
			ScribuntoUnit = true,&lt;br /&gt;
			text = mw.ustring.format(&amp;quot;Pattern type error (expected string, got %s)&amp;quot;, type(pattern)),&lt;br /&gt;
			message = message&lt;br /&gt;
		}, 2)&lt;br /&gt;
	end&lt;br /&gt;
	if type(s) ~= &#039;string&#039; then&lt;br /&gt;
		DebugHelper.raise({&lt;br /&gt;
			ScribuntoUnit = true,&lt;br /&gt;
			text = mw.ustring.format(&amp;quot;String type error (expected string, got %s)&amp;quot;, type(s)),&lt;br /&gt;
			message = message&lt;br /&gt;
		}, 2)&lt;br /&gt;
	end&lt;br /&gt;
	local i, j = mw.ustring.find(s, pattern, nil, plain)&lt;br /&gt;
	if i then&lt;br /&gt;
		local match = mw.ustring.sub(s, i, j)&lt;br /&gt;
		DebugHelper.raise({&lt;br /&gt;
			ScribuntoUnit = true,&lt;br /&gt;
			text = mw.ustring.format(&#039;Found match &amp;quot;%s&amp;quot; for %s &amp;quot;%s&amp;quot;&#039;, match, plain and &amp;quot;plain string&amp;quot; or &amp;quot;pattern&amp;quot;, pattern),&lt;br /&gt;
			message = message&lt;br /&gt;
		}, 2)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that an input has the expected value.&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertEquals(4, add(2,2), &amp;quot;2+2 should be 4&amp;quot;)&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:assertEquals(expected, actual, message)&lt;br /&gt;
&lt;br /&gt;
	if type(expected) == &#039;number&#039; and type(actual) == &#039;number&#039; then&lt;br /&gt;
        self:assertWithinDelta(expected, actual, 1e-8, message)&lt;br /&gt;
&lt;br /&gt;
	elseif expected ~= actual then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %s equals expected %s&amp;quot;, tostring(actual), tostring(expected)), &lt;br /&gt;
            actual = actual,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that &#039;actual&#039; is within &#039;delta&#039; of &#039;expected&#039;.&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertEquals(1/3, 9/3, &amp;quot;9/3 should be 1/3&amp;quot;, 0.000001)&lt;br /&gt;
function ScribuntoUnit:assertWithinDelta(expected, actual, delta, message)&lt;br /&gt;
    if type(expected) ~= &amp;quot;number&amp;quot; then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true,&lt;br /&gt;
            text = string.format(&amp;quot;Expected value %s is not a number&amp;quot;, tostring(expected)),&lt;br /&gt;
            actual = actual,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
    if type(actual) ~= &amp;quot;number&amp;quot; then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true,&lt;br /&gt;
            text = string.format(&amp;quot;Actual value %s is not a number&amp;quot;, tostring(actual)),&lt;br /&gt;
            actual = actual,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
    local diff = expected - actual&lt;br /&gt;
    if diff &amp;lt; 0 then diff = - diff end  -- instead of importing math.abs&lt;br /&gt;
    if diff &amp;gt; delta then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %f is within %f of expected %f&amp;quot;, actual, delta, expected), &lt;br /&gt;
            actual = actual,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that a table has the expected value (including sub-tables).&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertDeepEquals({{1,3}, {2,4}}, partition(odd, {1,2,3,4}))&lt;br /&gt;
function ScribuntoUnit:assertDeepEquals(expected, actual, message)&lt;br /&gt;
    if not DebugHelper.deepCompare(expected, actual) then&lt;br /&gt;
        if type(expected) == &#039;table&#039; then&lt;br /&gt;
            expected = mw.dumpObject(expected)&lt;br /&gt;
        end&lt;br /&gt;
        if type(actual) == &#039;table&#039; then&lt;br /&gt;
            actual = mw.dumpObject(actual)&lt;br /&gt;
        end&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %s equals expected %s&amp;quot;, tostring(actual), tostring(expected)), &lt;br /&gt;
            actual = actual,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that a wikitext gives the expected result after processing.&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertResultEquals(&amp;quot;Hello world&amp;quot;, &amp;quot;{{concat|Hello|world}}&amp;quot;)&lt;br /&gt;
function ScribuntoUnit:assertResultEquals(expected, text, message)&lt;br /&gt;
    local frame = self.frame&lt;br /&gt;
    local actual = frame:preprocess(text)&lt;br /&gt;
    if expected ~= actual then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %s equals expected %s after preprocessing&amp;quot;, text, tostring(expected)), &lt;br /&gt;
            actual = actual,&lt;br /&gt;
            actualRaw = text,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that two wikitexts give the same result after processing.&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertSameResult(&amp;quot;{{concat|Hello|world}}&amp;quot;, &amp;quot;{{deleteLastChar|Hello world!}}&amp;quot;)&lt;br /&gt;
function ScribuntoUnit:assertSameResult(text1, text2, message)&lt;br /&gt;
    local frame = self.frame&lt;br /&gt;
    local processed1 = frame:preprocess(text1)&lt;br /&gt;
    local processed2 = frame:preprocess(text2)&lt;br /&gt;
    if processed1 ~= processed2 then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %s equals expected %s after preprocessing&amp;quot;, processed1, processed2), &lt;br /&gt;
            actual = processed1,&lt;br /&gt;
            actualRaw = text1,&lt;br /&gt;
            expected = processed2,&lt;br /&gt;
            expectedRaw = text2,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that a parser function gives the expected output.&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertParserFunctionEquals(&amp;quot;Hello world&amp;quot;, &amp;quot;msg:concat&amp;quot;, {&amp;quot;Hello&amp;quot;, &amp;quot; world&amp;quot;})&lt;br /&gt;
function ScribuntoUnit:assertParserFunctionEquals(expected, pfname, args, message)&lt;br /&gt;
    local frame = self.frame&lt;br /&gt;
    local actual = frame:callParserFunction{ name = pfname, args = args}&lt;br /&gt;
    if expected ~= actual then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %s with args %s equals expected %s after preprocessing&amp;quot;, &lt;br /&gt;
                                 DebugHelper.concatWithKeys(args), pfname, expected),&lt;br /&gt;
            actual = actual,&lt;br /&gt;
            actualRaw = pfname,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that a template gives the expected output.&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertTemplateEquals(&amp;quot;Hello world&amp;quot;, &amp;quot;concat&amp;quot;, {&amp;quot;Hello&amp;quot;, &amp;quot; world&amp;quot;})&lt;br /&gt;
function ScribuntoUnit:assertTemplateEquals(expected, template, args, message)&lt;br /&gt;
    local frame = self.frame&lt;br /&gt;
    local actual = frame:expandTemplate{ title = template, args = args}&lt;br /&gt;
    if expected ~= actual then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %s with args %s equals expected %s after preprocessing&amp;quot;, &lt;br /&gt;
                                 DebugHelper.concatWithKeys(args), template, expected),&lt;br /&gt;
            actual = actual,&lt;br /&gt;
            actualRaw = template,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks whether a function throws an error&lt;br /&gt;
-- @param fn the function to test&lt;br /&gt;
-- @param expectedMessage optional the expected error message&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
function ScribuntoUnit:assertThrows(fn, expectedMessage, message)&lt;br /&gt;
    local succeeded, actualMessage = pcall(fn)&lt;br /&gt;
    if succeeded then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true,&lt;br /&gt;
            text = &#039;Expected exception but none was thrown&#039;,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
	-- For strings, strip the line number added to the error message&lt;br /&gt;
    actualMessage = type(actualMessage) == &#039;string&#039; &lt;br /&gt;
    	and string.match(actualMessage, &#039;Module:[^:]*:[0-9]*: (.*)&#039;)&lt;br /&gt;
    	or actualMessage&lt;br /&gt;
    local messagesMatch = DebugHelper.deepCompare(expectedMessage, actualMessage)&lt;br /&gt;
    if expectedMessage and not messagesMatch then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true,&lt;br /&gt;
            expected = expectedMessage,&lt;br /&gt;
            actual = actualMessage,&lt;br /&gt;
            text = string.format(&#039;Expected exception with message %s, but got message %s&#039;, &lt;br /&gt;
                tostring(expectedMessage), tostring(actualMessage)&lt;br /&gt;
            ),&lt;br /&gt;
            message = message&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks whether a function doesn&#039;t throw an error&lt;br /&gt;
-- @param fn the function to test&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
function ScribuntoUnit:assertDoesNotThrow(fn, message)&lt;br /&gt;
	local succeeded, actualMessage = pcall(fn)&lt;br /&gt;
	if succeeded then&lt;br /&gt;
	    return&lt;br /&gt;
	end&lt;br /&gt;
	-- For strings, strip the line number added to the error message&lt;br /&gt;
	actualMessage = type(actualMessage) == &#039;string&#039; &lt;br /&gt;
		and string.match(actualMessage, &#039;Module:[^:]*:[0-9]*: (.*)&#039;)&lt;br /&gt;
		or actualMessage&lt;br /&gt;
	DebugHelper.raise({&lt;br /&gt;
		ScribuntoUnit = true,&lt;br /&gt;
		actual = actualMessage,&lt;br /&gt;
		text = string.format(&#039;Expected no exception, but got exception with message %s&#039;,&lt;br /&gt;
			tostring(actualMessage)&lt;br /&gt;
		),&lt;br /&gt;
		message = message&lt;br /&gt;
	}, 2)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Creates a new test suite.&lt;br /&gt;
-- @param o a table with test functions (alternatively, the functions can be added later to the returned suite)&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:new(o)&lt;br /&gt;
    o = o or {}&lt;br /&gt;
    setmetatable(o, {__index = self})&lt;br /&gt;
    o.run = function(frame) return self:run(o, frame) end&lt;br /&gt;
    return o&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Resets global counters&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:init(frame)&lt;br /&gt;
    self.frame = frame or mw.getCurrentFrame()&lt;br /&gt;
    self.successCount = 0&lt;br /&gt;
    self.failureCount = 0&lt;br /&gt;
    self.skipCount = 0&lt;br /&gt;
    self.results = {}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Runs a single testcase&lt;br /&gt;
-- @param name test nume&lt;br /&gt;
-- @param test function containing assertions&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:runTest(suite, name, test)&lt;br /&gt;
    local success, details = pcall(test, suite)&lt;br /&gt;
    &lt;br /&gt;
    if success then&lt;br /&gt;
        self.successCount = self.successCount + 1&lt;br /&gt;
        table.insert(self.results, {name = name, success = true})&lt;br /&gt;
    elseif type(details) ~= &#039;table&#039; or not details.ScribuntoUnit then -- a real error, not a failed assertion&lt;br /&gt;
        self.failureCount = self.failureCount + 1&lt;br /&gt;
        table.insert(self.results, {name = name, error = true, message = &#039;Lua error -- &#039; .. tostring(details)})&lt;br /&gt;
    elseif details.skipped then&lt;br /&gt;
        self.skipCount = self.skipCount + 1&lt;br /&gt;
        table.insert(self.results, {name = name, skipped = true})&lt;br /&gt;
    else&lt;br /&gt;
        self.failureCount = self.failureCount + 1&lt;br /&gt;
        local message = details.source&lt;br /&gt;
        if details.message then&lt;br /&gt;
            message = message .. details.message .. &amp;quot;\n&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        message = message .. details.text&lt;br /&gt;
        table.insert(self.results, {name = name, error = true, message = message, expected = details.expected, actual = details.actual, testname = details.message})&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Runs all tests and displays the results.&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:runSuite(suite, frame)&lt;br /&gt;
    self:init(frame)&lt;br /&gt;
	local names = {}&lt;br /&gt;
    for name in pairs(suite) do&lt;br /&gt;
        if name:find(&#039;^test&#039;) then&lt;br /&gt;
			table.insert(names, name)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
	table.sort(names) -- Put tests in alphabetical order.&lt;br /&gt;
	for i, name in ipairs(names) do&lt;br /&gt;
		local func = suite[name]&lt;br /&gt;
		self:runTest(suite, name, func)&lt;br /&gt;
	end&lt;br /&gt;
    return {&lt;br /&gt;
        successCount = self.successCount,&lt;br /&gt;
        failureCount = self.failureCount,&lt;br /&gt;
        skipCount = self.skipCount,&lt;br /&gt;
        results = self.results,&lt;br /&gt;
    }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- #invoke entry point for running the tests.&lt;br /&gt;
-- Can be called without a frame, in which case it will use mw.log for output&lt;br /&gt;
-- @param displayMode see displayResults()&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:run(suite, frame)&lt;br /&gt;
    local testData = self:runSuite(suite, frame)&lt;br /&gt;
    if frame and frame.args then&lt;br /&gt;
        return self:displayResults(testData, frame.args.displayMode or &#039;table&#039;)&lt;br /&gt;
    else&lt;br /&gt;
        return self:displayResults(testData, &#039;log&#039;)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Displays test results &lt;br /&gt;
-- @param displayMode: &#039;table&#039;, &#039;log&#039; or &#039;short&#039;&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:displayResults(testData, displayMode)&lt;br /&gt;
    if displayMode == &#039;table&#039; then&lt;br /&gt;
        return self:displayResultsAsTable(testData)&lt;br /&gt;
    elseif displayMode == &#039;log&#039; then&lt;br /&gt;
        return self:displayResultsAsLog(testData)&lt;br /&gt;
    elseif displayMode == &#039;short&#039; then&lt;br /&gt;
        return self:displayResultsAsShort(testData)&lt;br /&gt;
    else&lt;br /&gt;
        error(&#039;unknown display mode&#039;)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ScribuntoUnit:displayResultsAsLog(testData)&lt;br /&gt;
    if testData.failureCount &amp;gt; 0 then&lt;br /&gt;
        mw.log(&#039;FAILURES!!!&#039;)&lt;br /&gt;
    elseif testData.skipCount &amp;gt; 0 then&lt;br /&gt;
        mw.log(&#039;Some tests could not be executed without a frame and have been skipped. Invoke this test suite as a template to run all tests.&#039;)&lt;br /&gt;
    end&lt;br /&gt;
    mw.log(string.format(&#039;Assertions: success: %d, error: %d, skipped: %d&#039;, testData.successCount, testData.failureCount, testData.skipCount))&lt;br /&gt;
    mw.log(&#039;-------------------------------------------------------------------------------&#039;)&lt;br /&gt;
    for _, result in ipairs(testData.results) do&lt;br /&gt;
        if result.error then&lt;br /&gt;
            mw.log(string.format(&#039;%s: %s&#039;, result.name, result.message))&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ScribuntoUnit:displayResultsAsShort(testData)&lt;br /&gt;
    local text = string.format(cfg.shortResultsFormat, testData.successCount, testData.failureCount, testData.skipCount)&lt;br /&gt;
    if testData.failureCount &amp;gt; 0 then&lt;br /&gt;
        text = &#039;&amp;lt;span class=&amp;quot;error&amp;quot;&amp;gt;&#039; .. text .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
    end&lt;br /&gt;
    return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ScribuntoUnit:displayResultsAsTable(testData)&lt;br /&gt;
    local successIcon, failIcon = self.frame:preprocess(cfg.successIndicator), self.frame:preprocess(cfg.failureIndicator)&lt;br /&gt;
    local text = &#039;&#039;&lt;br /&gt;
	if testData.failureCount &amp;gt; 0 then&lt;br /&gt;
		local msg = mw.message.newRawMessage(cfg.failureSummary, testData.failureCount):plain()&lt;br /&gt;
		msg = self.frame:preprocess(msg)&lt;br /&gt;
		if cfg.failureCategory then&lt;br /&gt;
			msg = cfg.failureCategory .. msg&lt;br /&gt;
		end&lt;br /&gt;
		text = text .. failIcon .. &#039; &#039; .. msg .. &#039;\n&#039;&lt;br /&gt;
	else&lt;br /&gt;
		text = text .. successIcon .. &#039; &#039; .. cfg.successSummary .. &#039;\n&#039;&lt;br /&gt;
	end&lt;br /&gt;
    text = text .. &#039;{| class=&amp;quot;wikitable scribunto-test-table&amp;quot;\n&#039;&lt;br /&gt;
    text = text .. &#039;!\n! &#039; .. cfg.nameString .. &#039;\n! &#039; .. cfg.expectedString .. &#039;\n! &#039; .. cfg.actualString .. &#039;\n&#039;&lt;br /&gt;
    for _, result in ipairs(testData.results) do&lt;br /&gt;
        text = text .. &#039;|-\n&#039;&lt;br /&gt;
        if result.error then&lt;br /&gt;
            text = text .. &#039;| &#039; .. failIcon .. &#039;\n| &#039;&lt;br /&gt;
            if (result.expected and result.actual) then&lt;br /&gt;
            	local name = result.name&lt;br /&gt;
            	if result.testname then&lt;br /&gt;
            		name = name .. &#039; / &#039; .. result.testname&lt;br /&gt;
            	end&lt;br /&gt;
                text = text .. name .. &#039;\n| &#039; .. mw.text.nowiki(tostring(result.expected)) .. &#039;\n| &#039; .. mw.text.nowiki(tostring(result.actual)) .. &#039;\n&#039;&lt;br /&gt;
            else&lt;br /&gt;
                text = text .. result.name .. &#039;\n| &#039; .. &#039; colspan=&amp;quot;2&amp;quot; | &#039; .. mw.text.nowiki(result.message) .. &#039;\n&#039;&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            text = text .. &#039;| &#039; .. successIcon .. &#039;\n| &#039; .. result.name .. &#039;\n|\n|\n&#039;&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    text = text .. &#039;|}\n&#039;&lt;br /&gt;
    return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return ScribuntoUnit&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:ModuleQuality&amp;diff=1726</id>
		<title>Template:ModuleQuality</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:ModuleQuality&amp;diff=1726"/>
		<updated>2024-01-05T17:23:48Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;includeonly&amp;gt;{{#ifexist:Module:{{{1|{{ROOTPAGENAME}}}}}/testcases|&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
{{(!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
{{!}}+ {{#invoke:TNT|msg|I18n/ModuleQuality.tab|testcases-table-caption}}&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} &amp;lt;noinclude&amp;gt;{{ns:module}}:{{parameter|{{#invoke:TNT|msg|I18n/ModuleQuality.tab|module-name}}}}&amp;lt;/noinclude&amp;gt;&amp;lt;!--&lt;br /&gt;
	--&amp;gt;&amp;lt;includeonly&amp;gt;[[:{{ns:module}}:{{{1|{{ROOTPAGENAME}}}}}]]&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
{{!}} {{&amp;lt;noinclude&amp;gt;tlg|nowrapname=1|nolink=1|mono=1|&amp;lt;/noinclude&amp;gt;#invoke:{{{1|{{ROOTPAGENAME}}}}}/testcases|run&amp;lt;!--&lt;br /&gt;
	--&amp;gt;|&amp;lt;noinclude&amp;gt;3=&amp;lt;/noinclude&amp;gt;displayMode=short&amp;lt;!--&lt;br /&gt;
--&amp;gt;}}&lt;br /&gt;
{{!}}-&lt;br /&gt;
&amp;lt;includeonly&amp;gt;{{#ifexist:Module:{{{1|{{ROOTPAGENAME}}}}}/sandbox|&amp;lt;nowiki/&amp;gt;&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;noinclude&amp;gt;{{ns:module}}:{{parameter|{{#invoke:TNT|msg|I18n/ModuleQuality.tab|module-name}}}}/sandbox&amp;lt;/noinclude&amp;gt;&amp;lt;!--&lt;br /&gt;
	--&amp;gt;&amp;lt;includeonly&amp;gt;[[:{{ns:module}}:{{{1|{{ROOTPAGENAME}}}}}/sandbox]]&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
{{!}} {{&amp;lt;noinclude&amp;gt;tlg|nowrapname=1|nolink=1|mono=1|&amp;lt;/noinclude&amp;gt;#invoke:{{{1|{{ROOTPAGENAME}}}}}/testcases|run&amp;lt;!--&lt;br /&gt;
	--&amp;gt;|&amp;lt;noinclude&amp;gt;3=&amp;lt;/noinclude&amp;gt;displayMode=short&amp;lt;!--&lt;br /&gt;
	--&amp;gt;|&amp;lt;noinclude&amp;gt;4=&amp;lt;/noinclude&amp;gt;module=&amp;lt;!--&lt;br /&gt;
		--&amp;gt;&amp;lt;noinclude&amp;gt;{{parameter|{{#invoke:TNT|msg|I18n/ModuleQuality.tab|module-name}}}}&amp;lt;/noinclude&amp;gt;&amp;lt;!--&lt;br /&gt;
		--&amp;gt;&amp;lt;includeonly&amp;gt;{{{1|{{ROOTPAGENAME}}}}}&amp;lt;/includeonly&amp;gt;/sandbox&amp;lt;!--&lt;br /&gt;
--&amp;gt;}}&lt;br /&gt;
&amp;lt;includeonly&amp;gt;}}&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
{{!)}}&lt;br /&gt;
* {{#invoke:TNT|msg|I18n/ModuleQuality.tab|see-testcases|3=:{{ns:module}}:&amp;lt;noinclude&amp;gt;{{parameter|{{#invoke:TNT|msg|I18n/ModuleQuality.tab|module-name}}}}&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;{{{1|{{ROOTPAGENAME}}}}}&amp;lt;/includeonly&amp;gt;/testcases}}&amp;lt;includeonly&amp;gt;&lt;br /&gt;
}}{{#ifexist:Module:{{{1|{{ROOTPAGENAME}}}}}/sandbox|&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
* &amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;{{#invoke:TNT|msg|I18n/ModuleQuality.tab|diff-sandbox|&amp;lt;noinclude&amp;gt;&amp;lt;nowiki/&amp;gt;&amp;lt;/noinclude&amp;gt;{{fullurl:Special:ComparePages&amp;lt;!--&lt;br /&gt;
--&amp;gt;|page1=&amp;lt;!--&lt;br /&gt;
	--&amp;gt;&amp;lt;noinclude&amp;gt;{{ns:module}}:{{parameter|{{#invoke:TNT|msg|I18n/ModuleQuality.tab|module-name}}}}&amp;lt;/noinclude&amp;gt;&amp;lt;!--&lt;br /&gt;
	--&amp;gt;&amp;lt;includeonly&amp;gt;{{urlencode:{{ns:module}}:{{{1|{{ROOTPAGENAME}}}}}|QUERY}}&amp;lt;/includeonly&amp;gt;&amp;lt;!--&lt;br /&gt;
--&amp;gt;&amp;amp;page2=&amp;lt;!--&lt;br /&gt;
	--&amp;gt;&amp;lt;noinclude&amp;gt;{{ns:module}}:{{parameter|{{#invoke:TNT|msg|I18n/ModuleQuality.tab|module-name}}}}/sandbox&amp;lt;/noinclude&amp;gt;&amp;lt;!--&lt;br /&gt;
	--&amp;gt;&amp;lt;includeonly&amp;gt;{{urlencode:Module:{{{1|{{ROOTPAGENAME}}}}}/sandbox|QUERY}}&amp;lt;/includeonly&amp;gt;&amp;lt;!--&lt;br /&gt;
--&amp;gt;}}}}&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;includeonly&amp;gt;}}&amp;lt;/includeonly&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;!-- Add categories to the /doc subpage and interwikis in Wikidata, not here! --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:Shared_Template_Warning&amp;diff=1724</id>
		<title>Template:Shared Template Warning</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:Shared_Template_Warning&amp;diff=1724"/>
		<updated>2024-01-05T17:23:47Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;{{ {{PAGENAME}}|Template:Shared Template Warning|Shared Template Warning}}{{Documentation}}&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;&amp;lt;table&lt;br /&gt;
	style=&amp;quot;background:#fee7e6; margin:0.5em 10%; border:1px solid #a2a9b1; border-collapse: collapse;&amp;quot;&lt;br /&gt;
&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border:none; padding:2px 0 2px 0.9em; text-align:center&amp;quot;&amp;gt;&amp;lt;!--&lt;br /&gt;
&amp;quot;&amp;gt;&amp;lt;!--&lt;br /&gt;
	--&amp;gt;[[File:OOjs UI icon notice-destructive.svg|20px|warning|link=]] &amp;lt;!--&lt;br /&gt;
	--&amp;gt;&amp;lt;span style=&amp;quot;white-space:nowrap&amp;quot;&amp;gt;&#039;&#039;&#039;{{#invoke:TNT|msg|I18n/Shared Template Warning.tab|warning}}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;!--&lt;br /&gt;
--&amp;gt;&amp;lt;!--&lt;br /&gt;
--&amp;gt;&amp;lt;td style=&amp;quot;border: none; padding: 0.25em 0.9em ;width: 100%&amp;quot;&amp;gt;&amp;lt;!--&lt;br /&gt;
 --&amp;gt;{{#ifeq:{{SITENAME}}|MediaWiki&amp;lt;!--&lt;br /&gt;
  --&amp;gt;|{{#invoke:TNT|msg|I18n/Shared Template Warning.tab|be-careful}}&amp;lt;!--&lt;br /&gt;
  --&amp;gt;|{{#invoke:TNT|msg|I18n/Shared Template Warning.tab|no-edit|{{{1}}}}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;}}{{#if:{{{2|}}}|&amp;lt;br&amp;gt;{{#invoke:TNT|msg|I18n/Shared Template Warning.tab|translate|c:Data:I18n/{{{2}}}.tab}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;}}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Uses_TNT/config&amp;diff=1722</id>
		<title>Module:Uses TNT/config</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Uses_TNT/config&amp;diff=1722"/>
		<updated>2024-01-05T17:23:46Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local cfg = {} -- Don’t touch this line.&lt;br /&gt;
&lt;br /&gt;
-- Subpage blacklist: these subpages will not be categorized (except for the&lt;br /&gt;
-- error category, which is always added if there is an error).&lt;br /&gt;
-- For example “Template:Foo/doc” matches the `doc = true` rule, so it will have&lt;br /&gt;
-- no categories. “Template:Foo” and “Template:Foo/documentation” match no rules,&lt;br /&gt;
-- so they *will* have categories. All rules should be in the&lt;br /&gt;
--   [&#039;&amp;lt;subpage name&amp;gt;&#039;] = true,&lt;br /&gt;
-- format.&lt;br /&gt;
cfg[&#039;subpage_blacklist&#039;] = {&lt;br /&gt;
	[&#039;doc&#039;] = true,&lt;br /&gt;
	[&#039;sandbox&#039;] = true,&lt;br /&gt;
	[&#039;sandbox2&#039;] = true,&lt;br /&gt;
	[&#039;testcases&#039;] = true,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Allow wishes: whether wishes for conversion to use [[Module:TNT]]&lt;br /&gt;
-- are implicitly allowed.&lt;br /&gt;
-- If `true`, calls with zero parameters are valid, and considered to be wishes:&lt;br /&gt;
-- The box’s text is “This template should use [[Module:TNT]]”, and&lt;br /&gt;
-- `cfg[&#039;wish_category&#039;]` is added.&lt;br /&gt;
-- If `false`, such calls are invalid unless the `|wish=` parameter is truthy,&lt;br /&gt;
-- an error message appears, and `cfg[&#039;error_category&#039;]` is added.&lt;br /&gt;
cfg[&#039;allow_wishes&#039;] = false&lt;br /&gt;
&lt;br /&gt;
-- Default category: this category is added if the module call contains errors&lt;br /&gt;
-- (e.g. no module listed). A category name without namespace, or nil&lt;br /&gt;
-- to disable categorization (not recommended).&lt;br /&gt;
cfg[&#039;error_category&#039;] = nil&lt;br /&gt;
&lt;br /&gt;
-- Wish category: this category is added if no module is listed, and wishes are&lt;br /&gt;
-- allowed. (Not used if wishes are not allowed.) A category name without&lt;br /&gt;
-- namespace, or nil to disable categorization.&lt;br /&gt;
cfg[&#039;wish_category&#039;] = nil&lt;br /&gt;
&lt;br /&gt;
-- Default category: this category is added if no custom category is specified&lt;br /&gt;
-- in module/template call. A category name without namespace, or nil&lt;br /&gt;
-- to disable categorization.&lt;br /&gt;
cfg[&#039;default_category&#039;] = &#039;Templates using Module:TNT for internationalisation&#039;&lt;br /&gt;
&lt;br /&gt;
-- Logo link: the link for the logo text. Set to nil to disable linking.&lt;br /&gt;
cfg[&amp;quot;logo_link&amp;quot;] = &#039;Special:MyLanguage/WP:TNT&#039;&lt;br /&gt;
&lt;br /&gt;
return cfg -- Don’t touch this line.&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Uses_TNT&amp;diff=1720</id>
		<title>Module:Uses TNT</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Uses_TNT&amp;diff=1720"/>
		<updated>2024-01-05T17:23:46Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
-- This module implements the {{Uses TNT}} template.&lt;br /&gt;
--&lt;br /&gt;
-- @module usesTNT&lt;br /&gt;
-- @alias  p&lt;br /&gt;
-- @author [[User:ExE Boss]]&lt;br /&gt;
-- @require [[Module:Uses TNT/config]]&lt;br /&gt;
-- @require [[Module:Arguments]]&lt;br /&gt;
-- @require [[Module:Func]]&lt;br /&gt;
-- @require [[Module:List]]&lt;br /&gt;
-- @require [[Module:Message box]]&lt;br /&gt;
-- @require [[Module:TNT]]&lt;br /&gt;
-- @require [[Module:TNTTools]]&lt;br /&gt;
-- @require [[Module:TableTools]]&lt;br /&gt;
-- @require [[Module:Yesno]]&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;strict&amp;quot;);&lt;br /&gt;
local checkType = require(&amp;quot;libraryUtil&amp;quot;).checkType;&lt;br /&gt;
local getArgs = require(&amp;quot;Module:Arguments&amp;quot;).getArgs;&lt;br /&gt;
local yesno = require(&amp;quot;Module:Yesno&amp;quot;);&lt;br /&gt;
local lists = require(&amp;quot;Module:List&amp;quot;);&lt;br /&gt;
local tableTools = require(&amp;quot;Module:TableTools&amp;quot;);&lt;br /&gt;
local messageBox = require(&amp;quot;Module:Message box&amp;quot;);&lt;br /&gt;
local TNTTabFull = require(&amp;quot;Module:TNTTools&amp;quot;).TNTTabFull;&lt;br /&gt;
&lt;br /&gt;
local format = require(&amp;quot;Module:Func&amp;quot;)&lt;br /&gt;
	.bind(require(&amp;quot;Module:TNT&amp;quot;).format, &amp;quot;I18n/Uses TNT.tab&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
local p = {};&lt;br /&gt;
&lt;br /&gt;
local function getConfig()&lt;br /&gt;
	return mw.loadData(&amp;quot;Module:Uses TNT/config&amp;quot;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local args = getArgs(frame, {&lt;br /&gt;
		wrappers = {&lt;br /&gt;
			&amp;quot;Template:Uses TNT&amp;quot;,&lt;br /&gt;
		},&lt;br /&gt;
	});&lt;br /&gt;
	return p._main(args);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(args, cfg)&lt;br /&gt;
	checkType(&amp;quot;_main&amp;quot;, 1, args, &amp;quot;table&amp;quot;);&lt;br /&gt;
	checkType(&amp;quot;_main&amp;quot;, 2, cfg, &amp;quot;table&amp;quot;, true);&lt;br /&gt;
	cfg = cfg or getConfig();&lt;br /&gt;
&lt;br /&gt;
	local tabFiles = tableTools.compressSparseArray(args);&lt;br /&gt;
	local box = p.renderBox(tabFiles, cfg, args);&lt;br /&gt;
	local trackingCategories = p.renderTrackingCategories(args, tabFiles, nil, cfg);&lt;br /&gt;
	return box .. trackingCategories;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderBox(tabFiles, cfg, args)&lt;br /&gt;
	checkType(&amp;quot;renderBox&amp;quot;, 1, tabFiles, &amp;quot;table&amp;quot;);&lt;br /&gt;
	checkType(&amp;quot;renderBox&amp;quot;, 2, cfg, &amp;quot;table&amp;quot;, true);&lt;br /&gt;
	checkType(&amp;quot;renderBox&amp;quot;, 3, args, &amp;quot;table&amp;quot;, true);&lt;br /&gt;
	cfg = cfg or getConfig();&lt;br /&gt;
&lt;br /&gt;
	local nsType = mw.title.getCurrentTitle():inNamespaces(828, 829) and &#039;module&#039; or &#039;template&#039;;&lt;br /&gt;
	local boxArgs = {};&lt;br /&gt;
&lt;br /&gt;
	if #tabFiles &amp;lt; 1 then&lt;br /&gt;
		if cfg[&amp;quot;allow_wishes&amp;quot;] or yesno(args and args.wish) then&lt;br /&gt;
			boxArgs.text = format(&amp;quot;wishtext-&amp;quot; .. nsType);&lt;br /&gt;
		else&lt;br /&gt;
			boxArgs.text = string.format(&#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;%s&amp;lt;/strong&amp;gt;&#039;, format(&amp;quot;error-emptylist&amp;quot;));&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		local tabFileLinks = {};&lt;br /&gt;
		for i, tabFile in ipairs(tabFiles) do&lt;br /&gt;
			local tabFileFull = TNTTabFull(tabFile);&lt;br /&gt;
			tabFileLinks[i] = string.format(&amp;quot;[[:c:Data:%s|%s]]&amp;quot;, tabFileFull, tabFileFull);&lt;br /&gt;
		end&lt;br /&gt;
		local tabFilesList = lists.makeList(&amp;quot;bulleted&amp;quot;, tabFileLinks);&lt;br /&gt;
		boxArgs.text = format(&amp;quot;header-&amp;quot; .. nsType) .. &amp;quot;\n&amp;quot; .. tabFilesList;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	boxArgs.type = &amp;quot;notice&amp;quot;;&lt;br /&gt;
	boxArgs.small = true;&lt;br /&gt;
	boxArgs.image = cfg[&amp;quot;logo_link&amp;quot;]&lt;br /&gt;
		and string.format(&amp;quot;[[%s|%s]]&amp;quot;, cfg[&amp;quot;logo_link&amp;quot;], format(&amp;quot;logo-alt&amp;quot;))&lt;br /&gt;
		or format(&amp;quot;logo-alt&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	return messageBox.main(&amp;quot;mbox&amp;quot;, boxArgs);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderTrackingCategories(args, tabFiles, titleObj, cfg)&lt;br /&gt;
	checkType(&amp;quot;renderTrackingCategories&amp;quot;, 1, args, &amp;quot;table&amp;quot;);&lt;br /&gt;
	checkType(&amp;quot;renderTrackingCategories&amp;quot;, 2, tabFiles, &amp;quot;table&amp;quot;);&lt;br /&gt;
	checkType(&amp;quot;renderTrackingCategories&amp;quot;, 3, titleObj, &amp;quot;table&amp;quot;, true);&lt;br /&gt;
	checkType(&amp;quot;renderTrackingCategories&amp;quot;, 4, cfg, &amp;quot;table&amp;quot;, true);&lt;br /&gt;
&lt;br /&gt;
	if yesno(args.nocat) then&lt;br /&gt;
		return &#039;&#039;;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	cfg = cfg or getConfig();&lt;br /&gt;
&lt;br /&gt;
	local cats = {};&lt;br /&gt;
&lt;br /&gt;
	-- Error category&lt;br /&gt;
	if #tabFiles &amp;lt; 1 and not (cfg[&amp;quot;allow_wishes&amp;quot;] or yesno(args.wish)) and cfg[&amp;quot;error_category&amp;quot;] then&lt;br /&gt;
		cats[#cats + 1] = cfg[&amp;quot;error_category&amp;quot;];&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- [[Module:TNT]] category&lt;br /&gt;
	titleObj = titleObj or mw.title.getCurrentTitle();&lt;br /&gt;
	if (&lt;br /&gt;
		(titleObj.namespace == 10 or titleObj.namespace == 828)&lt;br /&gt;
		and not cfg[&amp;quot;subpage_blacklist&amp;quot;][titleObj.subpageText]&lt;br /&gt;
	) then&lt;br /&gt;
		local category = args.category;&lt;br /&gt;
		if not category then&lt;br /&gt;
			if (cfg[&amp;quot;allow_wishes&amp;quot;] or yesno(args.wish)) and #tabFiles &amp;lt; 1 then&lt;br /&gt;
				category = cfg[&amp;quot;wish_category&amp;quot;];&lt;br /&gt;
			else&lt;br /&gt;
				category = cfg[&amp;quot;default_category&amp;quot;];&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if category then&lt;br /&gt;
			cats[#cats + 1] = category;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for i, cat in ipairs(cats) do&lt;br /&gt;
		cats[i] = string.format(&amp;quot;[[Category:%s]]&amp;quot;, cat);&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat(cats);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p;&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:TNTTools&amp;diff=1718</id>
		<title>Module:TNTTools</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:TNTTools&amp;diff=1718"/>
		<updated>2024-01-05T17:23:46Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;require(&amp;quot;strict&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local TNT = require(&#039;Module:TNT&#039;)&lt;br /&gt;
--local SD = require(&#039;Module:SimpleDebug&#039;)&lt;br /&gt;
&lt;br /&gt;
function p.TNTTabFull (TNTTab)&lt;br /&gt;
	if (string.sub(TNTTab, 1, 5)) ~= &#039;I18n/&#039; then&lt;br /&gt;
		TNTTab = &#039;I18n/&#039;..TNTTab&lt;br /&gt;
	end	&lt;br /&gt;
	if (string.sub(TNTTab, string.len(TNTTab)-3)) ~= &#039;.tab&#039; then&lt;br /&gt;
		TNTTab = TNTTab..&#039;.tab&#039;&lt;br /&gt;
	end	&lt;br /&gt;
	return TNTTab&lt;br /&gt;
end --TNTTabFull&lt;br /&gt;
&lt;br /&gt;
function p.TNTTabCommons (TNTTab)&lt;br /&gt;
	return &#039;Commons:Data:&#039;..p.TNTTabFull(TNTTab)&lt;br /&gt;
end	&lt;br /&gt;
&lt;br /&gt;
function p.LnkTNTTab (TNTTab)&lt;br /&gt;
	return &#039;[[&#039;..p.TNTTabCommons(TNTTab)..&#039;]]&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function I18nStr (TNTTab, S, IsMsg, params)&lt;br /&gt;
	TNTTab = p.TNTTabFull (TNTTab)&lt;br /&gt;
	local SEnd = TNT.format(TNTTab, S, unpack(params)) or &#039;&#039;&lt;br /&gt;
	if SEnd == &#039;&#039; then&lt;br /&gt;
		SEnd = TNT.formatInLanguage(&#039;en&#039;,TNTTab, S, unpack(params))&lt;br /&gt;
		if IsMsg then&lt;br /&gt;
			local icon = &#039;[[File:Arbcom ru editing.svg|12px|Not found &amp;quot;&#039;..S..&#039;&amp;quot; in current language. Click here for to edit it.|link=&#039;..p.TNTTabCommons(TNTTab)..&#039;]]&#039;&lt;br /&gt;
			SEnd = SEnd..icon	&lt;br /&gt;
		end	&lt;br /&gt;
	end	&lt;br /&gt;
	return SEnd&lt;br /&gt;
end --I18nStr&lt;br /&gt;
&lt;br /&gt;
function p.GetMsgP (TNTTab, S, ...)&lt;br /&gt;
	return I18nStr (TNTTab, S, true, {...})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.GetStrP (TNTTab, S, ...)&lt;br /&gt;
	return I18nStr (TNTTab, S, false, {...})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.TabTransCS (TNTTab, S, CaseSensitive)&lt;br /&gt;
	CaseSensitive = ((CaseSensitive ~= nil) and (CaseSensitive == true)) or true&lt;br /&gt;
	local Wds = TNT.format (p.TNTTabFull(TNTTab), S)&lt;br /&gt;
	if not CaseSensitive then&lt;br /&gt;
		Wds = string.lower (Wds)&lt;br /&gt;
	end	&lt;br /&gt;
    return mw.text.split (Wds, &#039;|&#039;)&lt;br /&gt;
end --TabTransCS&lt;br /&gt;
&lt;br /&gt;
function p.TabTransMT (TNTTab, S, MaxTrans)&lt;br /&gt;
	local FN = p.TNTTabFull(TNTTab)&lt;br /&gt;
	local tab = mw.text.split (TNT.format (FN, S), &#039;|&#039;)&lt;br /&gt;
	if #tab &amp;gt; MaxTrans then&lt;br /&gt;
		error (string.format(&#039;Found %s translations for &amp;quot;%s&amp;quot;. Search in [[:commons:data:%s]]&#039;,#tab,S,FN)) &lt;br /&gt;
							-- Translation not required&lt;br /&gt;
	end&lt;br /&gt;
	return tab&lt;br /&gt;
end --TabTransMT&lt;br /&gt;
&lt;br /&gt;
function p.SFoundInTNTArr (TNTTab, val, CaseSensitive, S)&lt;br /&gt;
	if (S == nil) or (S == &#039;&#039;) then&lt;br /&gt;
		error(&#039;Not arguments trying to find &amp;quot;&#039;..val..&#039;&amp;quot;&#039;) --It doesn&#039;t require translation, only for degug&lt;br /&gt;
	end	&lt;br /&gt;
	local Arr = p.TabTransCS (TNTTab, S, CaseSensitive)&lt;br /&gt;
	if not CaseSensitive then&lt;br /&gt;
		val = string.lower (val)&lt;br /&gt;
	end	&lt;br /&gt;
	for I, W in ipairs(Arr) do&lt;br /&gt;
		if W == val then&lt;br /&gt;
			return true&lt;br /&gt;
		end	&lt;br /&gt;
	end	&lt;br /&gt;
	return false&lt;br /&gt;
end --SFoundInTNTArr&lt;br /&gt;
&lt;br /&gt;
function p.IdxFromTabTrans (TNTTab, val, CaseSensitive, ...)&lt;br /&gt;
	local Arr = unpack(arg)&lt;br /&gt;
	if Arr == nil then&lt;br /&gt;
		error(&#039;Not arguments trying to find &amp;quot;&#039;..val..&#039;&amp;quot;&#039;) --It doesn&#039;t require translation, only for degug&lt;br /&gt;
	end	&lt;br /&gt;
	local Idx = 0&lt;br /&gt;
	for I, W in ipairs(Arr) do&lt;br /&gt;
		if p.SFoundInTNTArr (TNTTab, val, CaseSensitive, W) then&lt;br /&gt;
			Idx = I&lt;br /&gt;
			break&lt;br /&gt;
		end	&lt;br /&gt;
	end	&lt;br /&gt;
	return Idx&lt;br /&gt;
end	--IdxFromTabTrans&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Func&amp;diff=1716</id>
		<title>Module:Func</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Func&amp;diff=1716"/>
		<updated>2024-01-05T17:23:46Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
-- This module provies helper functions for manipulating Lua functions.&lt;br /&gt;
--&lt;br /&gt;
-- @module func&lt;br /&gt;
-- @alias  p&lt;br /&gt;
-- @author ExE Boss&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;strict&amp;quot;);&lt;br /&gt;
local checkTypeMulti = require(&amp;quot;libraryUtil&amp;quot;).checkTypeMulti;&lt;br /&gt;
&lt;br /&gt;
local p = {};&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Creates a bound function that calls `func` with the varargs passed to `bind`&lt;br /&gt;
-- preceding the varargs passed to the newly created bound function.&lt;br /&gt;
--&lt;br /&gt;
-- @param {function} func&lt;br /&gt;
-- @param {any} ...&lt;br /&gt;
-- @return {function}&lt;br /&gt;
-- @see https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Function/bind&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.bind(func, ...)&lt;br /&gt;
	checkTypeMulti(&amp;quot;bind&amp;quot;, 1, func, { &amp;quot;table&amp;quot;, &amp;quot;function&amp;quot; });&lt;br /&gt;
&lt;br /&gt;
	local length = select(&amp;quot;#&amp;quot;, ...);&lt;br /&gt;
	local args = {...};&lt;br /&gt;
&lt;br /&gt;
	return function(...)&lt;br /&gt;
		local callArgs = { unpack(args, 1, length) };&lt;br /&gt;
		local innerLength = select(&amp;quot;#&amp;quot;, ...);&lt;br /&gt;
		for i = 1, innerLength do&lt;br /&gt;
			callArgs[length + i] = select(i, ...);&lt;br /&gt;
		end&lt;br /&gt;
		return func(unpack(callArgs, 1, innerLength + length));&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p;&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:Uses_TNT&amp;diff=1714</id>
		<title>Template:Uses TNT</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:Uses_TNT&amp;diff=1714"/>
		<updated>2024-01-05T17:23:46Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;includeonly&amp;gt;{{safesubst:&amp;lt;noinclude/&amp;gt;#invoke:Uses TNT|main}}&amp;lt;/includeonly&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
{{Uses TNT|Module:TNT/testcases|nocat=1}}&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;!-- Add categories to the /doc subpage and interwikis in Wikidata, not here! --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Lua_banner/config&amp;diff=1712</id>
		<title>Module:Lua banner/config</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Lua_banner/config&amp;diff=1712"/>
		<updated>2024-01-05T17:23:46Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local cfg = {} -- Don’t touch this line.&lt;br /&gt;
&lt;br /&gt;
-- Subpage blacklist: these subpages will not be categorized (except for the&lt;br /&gt;
-- error category, which is always added if there is an error).&lt;br /&gt;
-- For example “Template:Foo/doc” matches the `doc = true` rule, so it will have&lt;br /&gt;
-- no categories. “Template:Foo” and “Template:Foo/documentation” match no rules,&lt;br /&gt;
-- so they *will* have categories. All rules should be in the&lt;br /&gt;
--   [&#039;&amp;lt;subpage name&amp;gt;&#039;] = true,&lt;br /&gt;
-- format.&lt;br /&gt;
cfg[&#039;subpage_blacklist&#039;] = {&lt;br /&gt;
	[&#039;doc&#039;] = true,&lt;br /&gt;
	[&#039;sandbox&#039;] = true,&lt;br /&gt;
	[&#039;sandbox2&#039;] = true,&lt;br /&gt;
	[&#039;testcases&#039;] = true,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Allow wishes: whether wishes for conversion to Lua are allowed.&lt;br /&gt;
-- If true, calls with zero parameters are valid, and considered to be wishes:&lt;br /&gt;
-- The box’s text is “This template should use Lua”, and cfg[&#039;wish_category&#039;] is&lt;br /&gt;
-- added. If false, such calls are invalid, an error message appears, and&lt;br /&gt;
-- cfg[&#039;error_category&#039;] is added.&lt;br /&gt;
cfg[&#039;allow_wishes&#039;] = false&lt;br /&gt;
&lt;br /&gt;
-- Default category: this category is added if the module call contains errors&lt;br /&gt;
-- (e.g. no module listed). A category name without namespace, or nil&lt;br /&gt;
-- to disable categorization (not recommended).&lt;br /&gt;
cfg[&#039;error_category&#039;] = &#039;Lua templates with errors&#039;&lt;br /&gt;
&lt;br /&gt;
-- Wish category: this category is added if no module is listed, and wishes are&lt;br /&gt;
-- allowed. (Not used if wishes are not allowed.) A category name without&lt;br /&gt;
-- namespace, or nil to disable categorization.&lt;br /&gt;
cfg[&#039;wish_category&#039;] = &#039;Lua-candidates&#039;&lt;br /&gt;
&lt;br /&gt;
-- Default category: this category is added if none of the below module_categories&lt;br /&gt;
-- matches the first module listed. A category name without namespace, or nil&lt;br /&gt;
-- to disable categorization.&lt;br /&gt;
cfg[&#039;default_category&#039;] = &#039;Lua-based templates&#039;&lt;br /&gt;
&lt;br /&gt;
-- Module categories: one of these categories is added if the first listed module&lt;br /&gt;
-- is the listed module (e.g. {{Lua|Module:String}} adds&lt;br /&gt;
-- [[Category:Lua String-based templates]].) Format:&lt;br /&gt;
--   [&#039;&amp;lt;module name&amp;gt;&#039;] = &#039;&amp;lt;category name&amp;gt;&#039;&lt;br /&gt;
-- where neither &amp;lt;module name&amp;gt; nor &amp;lt;category name&amp;gt; contains namespace. An empty&lt;br /&gt;
-- table (i.e. no module-based categorization) will suffice on smaller wikis.&lt;br /&gt;
cfg[&#039;module_categories&#039;] = {&lt;br /&gt;
	[&#039;String&#039;] = &#039;Lua String-based templates&#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return cfg -- Don’t touch this line.&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:Lua&amp;diff=1710</id>
		<title>Template:Lua</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:Lua&amp;diff=1710"/>
		<updated>2024-01-05T17:23:46Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;includeonly&amp;gt;{{#invoke:Lua banner|main}}&amp;lt;/includeonly&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
{{Lua|Module:Lua banner}}&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go on the /doc subpage and interwikis go on Wikidata. --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:TableTools&amp;diff=1708</id>
		<title>Module:TableTools</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:TableTools&amp;diff=1708"/>
		<updated>2024-01-05T17:23:45Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--                               TableTools                                       --&lt;br /&gt;
--                                                                                --&lt;br /&gt;
-- This module includes a number of functions for dealing with Lua tables.        --&lt;br /&gt;
-- It is a meta-module, meant to be called from other Lua modules, and should     --&lt;br /&gt;
-- not be called directly from #invoke.                                           --&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
local libraryUtil = require(&#039;libraryUtil&#039;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Define often-used variables and functions.&lt;br /&gt;
local floor = math.floor&lt;br /&gt;
local infinity = math.huge&lt;br /&gt;
local checkType = libraryUtil.checkType&lt;br /&gt;
local checkTypeMulti = libraryUtil.checkTypeMulti&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- isPositiveInteger&lt;br /&gt;
--&lt;br /&gt;
-- This function returns true if the given value is a positive integer, and false&lt;br /&gt;
-- if not. Although it doesn&#039;t operate on tables, it is included here as it is&lt;br /&gt;
-- useful for determining whether a given table key is in the array part or the&lt;br /&gt;
-- hash part of a table.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.isPositiveInteger(v)&lt;br /&gt;
	if type(v) == &#039;number&#039; and v &amp;gt;= 1 and floor(v) == v and v &amp;lt; infinity then&lt;br /&gt;
		return true&lt;br /&gt;
	else&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- isNan&lt;br /&gt;
--&lt;br /&gt;
-- This function returns true if the given number is a NaN value, and false&lt;br /&gt;
-- if not. Although it doesn&#039;t operate on tables, it is included here as it is&lt;br /&gt;
-- useful for determining whether a value can be a valid table key. Lua will&lt;br /&gt;
-- generate an error if a NaN is used as a table key.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.isNan(v)&lt;br /&gt;
	if type(v) == &#039;number&#039; and tostring(v) == &#039;-nan&#039; then&lt;br /&gt;
		return true&lt;br /&gt;
	else&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- shallowClone&lt;br /&gt;
--&lt;br /&gt;
-- This returns a clone of a table. The value returned is a new table, but all&lt;br /&gt;
-- subtables and functions are shared. Metamethods are respected, but the returned&lt;br /&gt;
-- table will have no metatable of its own.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.shallowClone(t)&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		ret[k] = v&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- removeDuplicates&lt;br /&gt;
--&lt;br /&gt;
-- This removes duplicate values from an array. Non-positive-integer keys are&lt;br /&gt;
-- ignored. The earliest value is kept, and all subsequent duplicate values are&lt;br /&gt;
-- removed, but otherwise the array order is unchanged.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.removeDuplicates(t)&lt;br /&gt;
	checkType(&#039;removeDuplicates&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	local isNan = p.isNan&lt;br /&gt;
	local ret, exists = {}, {}&lt;br /&gt;
	for i, v in ipairs(t) do&lt;br /&gt;
		if isNan(v) then&lt;br /&gt;
			-- NaNs can&#039;t be table keys, and they are also unique, so we don&#039;t need to check existence.&lt;br /&gt;
			ret[#ret + 1] = v&lt;br /&gt;
		else&lt;br /&gt;
			if not exists[v] then&lt;br /&gt;
				ret[#ret + 1] = v&lt;br /&gt;
				exists[v] = true&lt;br /&gt;
			end&lt;br /&gt;
		end	&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end			&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- numKeys&lt;br /&gt;
--&lt;br /&gt;
-- This takes a table and returns an array containing the numbers of any numerical&lt;br /&gt;
-- keys that have non-nil values, sorted in numerical order.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.numKeys(t)&lt;br /&gt;
	checkType(&#039;numKeys&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	local isPositiveInteger = p.isPositiveInteger&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		if isPositiveInteger(k) then&lt;br /&gt;
			nums[#nums + 1] = k&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(nums)&lt;br /&gt;
	return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- affixNums&lt;br /&gt;
--&lt;br /&gt;
-- This takes a table and returns an array containing the numbers of keys with the&lt;br /&gt;
-- specified prefix and suffix. For example, for the table&lt;br /&gt;
-- {a1 = &#039;foo&#039;, a3 = &#039;bar&#039;, a6 = &#039;baz&#039;} and the prefix &amp;quot;a&amp;quot;, affixNums will&lt;br /&gt;
-- return {1, 3, 6}.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.affixNums(t, prefix, suffix)&lt;br /&gt;
	checkType(&#039;affixNums&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	checkType(&#039;affixNums&#039;, 2, prefix, &#039;string&#039;, true)&lt;br /&gt;
	checkType(&#039;affixNums&#039;, 3, suffix, &#039;string&#039;, true)&lt;br /&gt;
&lt;br /&gt;
	local function cleanPattern(s)&lt;br /&gt;
		-- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally.&lt;br /&gt;
		s = s:gsub(&#039;([%(%)%%%.%[%]%*%+%-%?%^%$])&#039;, &#039;%%%1&#039;)&lt;br /&gt;
		return s&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	prefix = prefix or &#039;&#039;&lt;br /&gt;
	suffix = suffix or &#039;&#039;&lt;br /&gt;
	prefix = cleanPattern(prefix)&lt;br /&gt;
	suffix = cleanPattern(suffix)&lt;br /&gt;
	local pattern = &#039;^&#039; .. prefix .. &#039;([1-9]%d*)&#039; .. suffix .. &#039;$&#039;&lt;br /&gt;
&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		if type(k) == &#039;string&#039; then			&lt;br /&gt;
			local num = mw.ustring.match(k, pattern)&lt;br /&gt;
			if num then&lt;br /&gt;
				nums[#nums + 1] = tonumber(num)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(nums)&lt;br /&gt;
	return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- numData&lt;br /&gt;
--&lt;br /&gt;
-- Given a table with keys like (&amp;quot;foo1&amp;quot;, &amp;quot;bar1&amp;quot;, &amp;quot;foo2&amp;quot;, &amp;quot;baz2&amp;quot;), returns a table&lt;br /&gt;
-- of subtables in the format &lt;br /&gt;
-- { [1] = {foo = &#039;text&#039;, bar = &#039;text&#039;}, [2] = {foo = &#039;text&#039;, baz = &#039;text&#039;} }&lt;br /&gt;
-- Keys that don&#039;t end with an integer are stored in a subtable named &amp;quot;other&amp;quot;.&lt;br /&gt;
-- The compress option compresses the table so that it can be iterated over with&lt;br /&gt;
-- ipairs.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.numData(t, compress)&lt;br /&gt;
	checkType(&#039;numData&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	checkType(&#039;numData&#039;, 2, compress, &#039;boolean&#039;, true)&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		local prefix, num = mw.ustring.match(tostring(k), &#039;^([^0-9]*)([1-9][0-9]*)$&#039;)&lt;br /&gt;
		if num then&lt;br /&gt;
			num = tonumber(num)&lt;br /&gt;
			local subtable = ret[num] or {}&lt;br /&gt;
			if prefix == &#039;&#039; then&lt;br /&gt;
				-- Positional parameters match the blank string; put them at the start of the subtable instead.&lt;br /&gt;
				prefix = 1&lt;br /&gt;
			end&lt;br /&gt;
			subtable[prefix] = v&lt;br /&gt;
			ret[num] = subtable&lt;br /&gt;
		else&lt;br /&gt;
			local subtable = ret.other or {}&lt;br /&gt;
			subtable[k] = v&lt;br /&gt;
			ret.other = subtable&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if compress then&lt;br /&gt;
		local other = ret.other&lt;br /&gt;
		ret = p.compressSparseArray(ret)&lt;br /&gt;
		ret.other = other&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- compressSparseArray&lt;br /&gt;
--&lt;br /&gt;
-- This takes an array with one or more nil values, and removes the nil values&lt;br /&gt;
-- while preserving the order, so that the array can be safely traversed with&lt;br /&gt;
-- ipairs.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.compressSparseArray(t)&lt;br /&gt;
	checkType(&#039;compressSparseArray&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	local nums = p.numKeys(t)&lt;br /&gt;
	for _, num in ipairs(nums) do&lt;br /&gt;
		ret[#ret + 1] = t[num]&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- sparseIpairs&lt;br /&gt;
--&lt;br /&gt;
-- This is an iterator for sparse arrays. It can be used like ipairs, but can&lt;br /&gt;
-- handle nil values.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function p.sparseIpairs(t)&lt;br /&gt;
	checkType(&#039;sparseIpairs&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	local nums = p.numKeys(t)&lt;br /&gt;
	local i = 0&lt;br /&gt;
	local lim = #nums&lt;br /&gt;
	return function ()&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		if i &amp;lt;= lim then&lt;br /&gt;
			local key = nums[i]&lt;br /&gt;
			return key, t[key]&lt;br /&gt;
		else&lt;br /&gt;
			return nil, nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- size&lt;br /&gt;
--&lt;br /&gt;
-- This returns the size of a key/value pair table. It will also work on arrays,&lt;br /&gt;
-- but for arrays it is more efficient to use the # operator.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
function p.size(t)&lt;br /&gt;
	checkType(&#039;size&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	local i = 0&lt;br /&gt;
	for k in pairs(t) do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return i&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function defaultKeySort(item1, item2)&lt;br /&gt;
	-- &amp;quot;number&amp;quot; &amp;lt; &amp;quot;string&amp;quot;, so numbers will be sorted before strings.&lt;br /&gt;
	local type1, type2 = type(item1), type(item2)&lt;br /&gt;
	if type1 ~= type2 then&lt;br /&gt;
		return type1 &amp;lt; type2&lt;br /&gt;
	else -- This will fail with table, boolean, function.&lt;br /&gt;
		return item1 &amp;lt; item2&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Returns a list of the keys in a table, sorted using either a default&lt;br /&gt;
	comparison function or a custom keySort function.&lt;br /&gt;
]]&lt;br /&gt;
function p.keysToList(t, keySort, checked)&lt;br /&gt;
	if not checked then&lt;br /&gt;
		checkType(&#039;keysToList&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
		checkTypeMulti(&#039;keysToList&#039;, 2, keySort, { &#039;function&#039;, &#039;boolean&#039;, &#039;nil&#039; })&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local list = {}&lt;br /&gt;
	local index = 1&lt;br /&gt;
	for key, value in pairs(t) do&lt;br /&gt;
		list[index] = key&lt;br /&gt;
		index = index + 1&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if keySort ~= false then&lt;br /&gt;
		keySort = type(keySort) == &#039;function&#039; and keySort or defaultKeySort&lt;br /&gt;
		&lt;br /&gt;
		table.sort(list, keySort)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return list&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Iterates through a table, with the keys sorted using the keysToList function.&lt;br /&gt;
	If there are only numerical keys, sparseIpairs is probably more efficient.&lt;br /&gt;
]]&lt;br /&gt;
function p.sortedPairs(t, keySort)&lt;br /&gt;
	checkType(&#039;sortedPairs&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	checkType(&#039;sortedPairs&#039;, 2, keySort, &#039;function&#039;, true)&lt;br /&gt;
	&lt;br /&gt;
	local list = p.keysToList(t, keySort, true)&lt;br /&gt;
	&lt;br /&gt;
	local i = 0&lt;br /&gt;
	return function()&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		local key = list[i]&lt;br /&gt;
		if key ~= nil then&lt;br /&gt;
			return key, t[key]&lt;br /&gt;
		else&lt;br /&gt;
			return nil, nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Returns true if all keys in the table are consecutive integers starting at 1.&lt;br /&gt;
--]]&lt;br /&gt;
function p.isArray(t)&lt;br /&gt;
	checkType(&amp;quot;isArray&amp;quot;, 1, t, &amp;quot;table&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	local i = 0&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		if t[i] == nil then&lt;br /&gt;
			return false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- { &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot; } -&amp;gt; { a = 1, b = 2, c = 3 }&lt;br /&gt;
function p.invert(array)&lt;br /&gt;
	checkType(&amp;quot;invert&amp;quot;, 1, array, &amp;quot;table&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	local map = {}&lt;br /&gt;
	for i, v in ipairs(array) do&lt;br /&gt;
		map[v] = i&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return map&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	{ &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot; } -&amp;gt; { [&amp;quot;a&amp;quot;] = true, [&amp;quot;b&amp;quot;] = true, [&amp;quot;c&amp;quot;] = true }&lt;br /&gt;
--]]&lt;br /&gt;
function p.listToSet(t)&lt;br /&gt;
	checkType(&amp;quot;listToSet&amp;quot;, 1, t, &amp;quot;table&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	local set = {}&lt;br /&gt;
	for _, item in ipairs(t) do&lt;br /&gt;
		set[item] = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return set&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Recursive deep copy function.&lt;br /&gt;
	Preserves identities of subtables.&lt;br /&gt;
	&lt;br /&gt;
]]&lt;br /&gt;
local function _deepCopy(orig, includeMetatable, already_seen)&lt;br /&gt;
	-- Stores copies of tables indexed by the original table.&lt;br /&gt;
	already_seen = already_seen or {}&lt;br /&gt;
	&lt;br /&gt;
	local copy = already_seen[orig]&lt;br /&gt;
	if copy ~= nil then&lt;br /&gt;
		return copy&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if type(orig) == &#039;table&#039; then&lt;br /&gt;
		copy = {}&lt;br /&gt;
		for orig_key, orig_value in pairs(orig) do&lt;br /&gt;
			copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen)&lt;br /&gt;
		end&lt;br /&gt;
		already_seen[orig] = copy&lt;br /&gt;
		&lt;br /&gt;
		if includeMetatable then&lt;br /&gt;
			local mt = getmetatable(orig)&lt;br /&gt;
			if mt ~= nil then&lt;br /&gt;
				local mt_copy = deepcopy(mt, includeMetatable, already_seen)&lt;br /&gt;
				setmetatable(copy, mt_copy)&lt;br /&gt;
				already_seen[mt] = mt_copy&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else -- number, string, boolean, etc&lt;br /&gt;
		copy = orig&lt;br /&gt;
	end&lt;br /&gt;
	return copy&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.deepCopy(orig, noMetatable, already_seen)&lt;br /&gt;
	checkType(&amp;quot;deepCopy&amp;quot;, 3, already_seen, &amp;quot;table&amp;quot;, true)&lt;br /&gt;
	&lt;br /&gt;
	return _deepCopy(orig, not noMetatable, already_seen)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Concatenates all values in the table that are indexed by a number, in order.&lt;br /&gt;
	sparseConcat{ a, nil, c, d }  =&amp;gt;  &amp;quot;acd&amp;quot;&lt;br /&gt;
	sparseConcat{ nil, b, c, d }  =&amp;gt;  &amp;quot;bcd&amp;quot;&lt;br /&gt;
]]&lt;br /&gt;
function p.sparseConcat(t, sep, i, j)&lt;br /&gt;
	local list = {}&lt;br /&gt;
	&lt;br /&gt;
	local list_i = 0&lt;br /&gt;
	for _, v in p.sparseIpairs(t) do&lt;br /&gt;
		list_i = list_i + 1&lt;br /&gt;
		list[list_i] = v&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return table.concat(list, sep, i, j)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
-- This returns the length of a table, or the first integer key n counting from&lt;br /&gt;
-- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return&lt;br /&gt;
-- a different value when there are gaps in the array portion of the table.&lt;br /&gt;
-- Intended to be used on data loaded with mw.loadData. For other tables, use #.&lt;br /&gt;
-- Note: #frame.args in frame object always be set to 0, regardless of &lt;br /&gt;
-- the number of unnamed template parameters, so use this function for&lt;br /&gt;
-- frame.args.&lt;br /&gt;
--]]&lt;br /&gt;
function p.length(t)&lt;br /&gt;
	local i = 1&lt;br /&gt;
	while t[i] ~= nil do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return i - 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.inArray(arr, valueToFind)&lt;br /&gt;
	checkType(&amp;quot;inArray&amp;quot;, 1, arr, &amp;quot;table&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	-- if valueToFind is nil, error?&lt;br /&gt;
	&lt;br /&gt;
	for _, v in ipairs(arr) do&lt;br /&gt;
		if v == valueToFind then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:List&amp;diff=1706</id>
		<title>Module:List</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:List&amp;diff=1706"/>
		<updated>2024-01-05T17:23:45Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module outputs different kinds of lists. At the moment, bulleted,&lt;br /&gt;
-- unbulleted, horizontal, ordered, and horizontal ordered lists are supported.&lt;br /&gt;
&lt;br /&gt;
local libUtil = require(&#039;libraryUtil&#039;)&lt;br /&gt;
local checkType = libUtil.checkType&lt;br /&gt;
local mTableTools = require(&#039;Module:TableTools&#039;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local listTypes = {&lt;br /&gt;
	[&#039;bulleted&#039;] = true,&lt;br /&gt;
	[&#039;unbulleted&#039;] = true,&lt;br /&gt;
	[&#039;horizontal&#039;] = true,&lt;br /&gt;
	[&#039;ordered&#039;] = true,&lt;br /&gt;
	[&#039;horizontal_ordered&#039;] = true&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function p.makeListData(listType, args)&lt;br /&gt;
	-- Constructs a data table to be passed to p.renderList.&lt;br /&gt;
	local data = {}&lt;br /&gt;
&lt;br /&gt;
	-- Classes&lt;br /&gt;
	data.classes = {}&lt;br /&gt;
	data.templatestyles = &#039;&#039;&lt;br /&gt;
	if listType == &#039;horizontal&#039; or listType == &#039;horizontal_ordered&#039; then&lt;br /&gt;
		table.insert(data.classes, &#039;hlist&#039;)&lt;br /&gt;
		data.templatestyles = mw.getCurrentFrame():extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;, args = { src = &#039;Flatlist/styles.css&#039; }&lt;br /&gt;
		}&lt;br /&gt;
	elseif listType == &#039;unbulleted&#039; then&lt;br /&gt;
		table.insert(data.classes, &#039;plainlist&#039;)&lt;br /&gt;
		data.templatestyles = mw.getCurrentFrame():extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;, args = { src = &#039;Plainlist/styles.css&#039; }&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	table.insert(data.classes, args.class)&lt;br /&gt;
&lt;br /&gt;
	-- Main div style&lt;br /&gt;
	data.style = args.style&lt;br /&gt;
&lt;br /&gt;
	-- Indent for horizontal lists&lt;br /&gt;
	if listType == &#039;horizontal&#039; or listType == &#039;horizontal_ordered&#039; then&lt;br /&gt;
		local indent = tonumber(args.indent)&lt;br /&gt;
		indent = indent and indent * 1.6 or 0&lt;br /&gt;
		if indent &amp;gt; 0 then&lt;br /&gt;
			data.marginLeft = indent .. &#039;em&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- List style types for ordered lists&lt;br /&gt;
	-- This could be &amp;quot;1, 2, 3&amp;quot;, &amp;quot;a, b, c&amp;quot;, or a number of others. The list style&lt;br /&gt;
	-- type is either set by the &amp;quot;type&amp;quot; attribute or the &amp;quot;list-style-type&amp;quot; CSS&lt;br /&gt;
	-- property.&lt;br /&gt;
	if listType == &#039;ordered&#039; or listType == &#039;horizontal_ordered&#039; then &lt;br /&gt;
		data.listStyleType = args.list_style_type or args[&#039;list-style-type&#039;]&lt;br /&gt;
		data.type = args[&#039;type&#039;]&lt;br /&gt;
&lt;br /&gt;
		-- Detect invalid type attributes and attempt to convert them to&lt;br /&gt;
		-- list-style-type CSS properties.&lt;br /&gt;
		if data.type &lt;br /&gt;
			and not data.listStyleType&lt;br /&gt;
			and not tostring(data.type):find(&#039;^%s*[1AaIi]%s*$&#039;)&lt;br /&gt;
		then&lt;br /&gt;
			data.listStyleType = data.type&lt;br /&gt;
			data.type = nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- List tag type&lt;br /&gt;
	if listType == &#039;ordered&#039; or listType == &#039;horizontal_ordered&#039; then&lt;br /&gt;
		data.listTag = &#039;ol&#039;&lt;br /&gt;
	else&lt;br /&gt;
		data.listTag = &#039;ul&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Start number for ordered lists&lt;br /&gt;
	data.start = args.start&lt;br /&gt;
	if listType == &#039;horizontal_ordered&#039; then&lt;br /&gt;
		-- Apply fix to get start numbers working with horizontal ordered lists.&lt;br /&gt;
		local startNum = tonumber(data.start)&lt;br /&gt;
		if startNum then&lt;br /&gt;
			data.counterReset = &#039;listitem &#039; .. tostring(startNum - 1)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- List style&lt;br /&gt;
	 -- ul_style and ol_style are included for backwards compatibility. No&lt;br /&gt;
	 -- distinction is made for ordered or unordered lists.&lt;br /&gt;
	data.listStyle = args.list_style&lt;br /&gt;
&lt;br /&gt;
	-- List items&lt;br /&gt;
	-- li_style is included for backwards compatibility. item_style was included&lt;br /&gt;
	-- to be easier to understand for non-coders.&lt;br /&gt;
	data.itemStyle = args.item_style or args.li_style&lt;br /&gt;
	data.items = {}&lt;br /&gt;
	for i, num in ipairs(mTableTools.numKeys(args)) do&lt;br /&gt;
		local item = {}&lt;br /&gt;
		item.content = args[num]&lt;br /&gt;
		item.style = args[&#039;item&#039; .. tostring(num) .. &#039;_style&#039;]&lt;br /&gt;
			or args[&#039;item_style&#039; .. tostring(num)]&lt;br /&gt;
		item.value = args[&#039;item&#039; .. tostring(num) .. &#039;_value&#039;]&lt;br /&gt;
			or args[&#039;item_value&#039; .. tostring(num)]&lt;br /&gt;
		table.insert(data.items, item)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return data&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderList(data)&lt;br /&gt;
	-- Renders the list HTML.&lt;br /&gt;
	&lt;br /&gt;
	-- Return the blank string if there are no list items.&lt;br /&gt;
	if type(data.items) ~= &#039;table&#039; or #data.items &amp;lt; 1 then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Render the main div tag.&lt;br /&gt;
	local root = mw.html.create((&lt;br /&gt;
			#data.classes &amp;gt; 0&lt;br /&gt;
			or data.marginLeft&lt;br /&gt;
			or data.style&lt;br /&gt;
		) and &#039;div&#039; or nil)&lt;br /&gt;
&lt;br /&gt;
	for i, class in ipairs(data.classes or {}) do&lt;br /&gt;
		root:addClass(class)&lt;br /&gt;
	end&lt;br /&gt;
	root:css{[&#039;margin-left&#039;] = data.marginLeft}&lt;br /&gt;
	if data.style then&lt;br /&gt;
		root:cssText(data.style)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Render the list tag.&lt;br /&gt;
	local list = root:tag(data.listTag or &#039;ul&#039;)&lt;br /&gt;
	list&lt;br /&gt;
		:attr{start = data.start, type = data.type}&lt;br /&gt;
		:css{&lt;br /&gt;
			[&#039;counter-reset&#039;] = data.counterReset,&lt;br /&gt;
			[&#039;list-style-type&#039;] = data.listStyleType&lt;br /&gt;
		}&lt;br /&gt;
	if data.listStyle then&lt;br /&gt;
		list:cssText(data.listStyle)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Render the list items&lt;br /&gt;
	for i, t in ipairs(data.items or {}) do&lt;br /&gt;
		local item = list:tag(&#039;li&#039;)&lt;br /&gt;
		if data.itemStyle then&lt;br /&gt;
			item:cssText(data.itemStyle)&lt;br /&gt;
		end&lt;br /&gt;
		if t.style then&lt;br /&gt;
			item:cssText(t.style)&lt;br /&gt;
		end&lt;br /&gt;
		item&lt;br /&gt;
			:attr{value = t.value}&lt;br /&gt;
			:wikitext(t.content)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return data.templatestyles .. tostring(root)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.makeList(listType, args)&lt;br /&gt;
	if not listType or not listTypes[listType] then&lt;br /&gt;
		error(string.format(&lt;br /&gt;
			&amp;quot;bad argument #1 to &#039;makeList&#039; (&#039;%s&#039; is not a valid list type)&amp;quot;,&lt;br /&gt;
			tostring(listType)&lt;br /&gt;
		), 2)&lt;br /&gt;
	end&lt;br /&gt;
	checkType(&#039;makeList&#039;, 2, args, &#039;table&#039;)&lt;br /&gt;
	local data = p.makeListData(listType, args)&lt;br /&gt;
	return p.renderList(data)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
for listType in pairs(listTypes) do&lt;br /&gt;
	p[listType] = function (frame)&lt;br /&gt;
		local mArguments = require(&#039;Module:Arguments&#039;)&lt;br /&gt;
		local origArgs = mArguments.getArgs(frame)&lt;br /&gt;
		-- Copy all the arguments to a new table, for faster indexing.&lt;br /&gt;
		local args = {}&lt;br /&gt;
		for k, v in pairs(origArgs) do&lt;br /&gt;
			args[k] = v&lt;br /&gt;
		end&lt;br /&gt;
		return p.makeList(listType, args)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Lua_banner&amp;diff=1704</id>
		<title>Module:Lua banner</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Lua_banner&amp;diff=1704"/>
		<updated>2024-01-05T17:23:45Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module implements the {{lua}} template.&lt;br /&gt;
&lt;br /&gt;
local yesno = require(&#039;Module:Yesno&#039;)&lt;br /&gt;
local mList = require(&#039;Module:List&#039;)&lt;br /&gt;
local mTableTools = require(&#039;Module:TableTools&#039;)&lt;br /&gt;
local mMessageBox = require(&#039;Module:Message box&#039;)&lt;br /&gt;
local TNT = require(&#039;Module:TNT&#039;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local function format(msg)&lt;br /&gt;
	return TNT.format(&#039;I18n/Lua banner&#039;, msg)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getConfig()&lt;br /&gt;
	return mw.loadData(&#039;Module:Lua banner/config&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local origArgs = frame:getParent().args&lt;br /&gt;
	local args = {}&lt;br /&gt;
	for k, v in pairs(origArgs) do&lt;br /&gt;
		v = v:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
		if v ~= &#039;&#039; then&lt;br /&gt;
			args[k] = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return p._main(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(args, cfg)&lt;br /&gt;
	local modules = mTableTools.compressSparseArray(args)&lt;br /&gt;
	local box = p.renderBox(modules, cfg, args)&lt;br /&gt;
	local trackingCategories = p.renderTrackingCategories(args, modules, nil, cfg)&lt;br /&gt;
	return box .. trackingCategories&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderBox(modules, cfg, args)&lt;br /&gt;
	local boxArgs = {}&lt;br /&gt;
	if #modules &amp;lt; 1 then&lt;br /&gt;
		cfg = cfg or getConfig()&lt;br /&gt;
		if cfg[&#039;allow_wishes&#039;] or yesno(args and args.wish) then&lt;br /&gt;
			boxArgs.text = format(&#039;wishtext&#039;)&lt;br /&gt;
		else&lt;br /&gt;
			boxArgs.text = string.format(&#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;%s&amp;lt;/strong&amp;gt;&#039;, format(&#039;error_emptylist&#039;))&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		local moduleLinks = {}&lt;br /&gt;
		for i, module in ipairs(modules) do&lt;br /&gt;
			moduleLinks[i] = string.format(&#039;[[:%s]]&#039;, module)&lt;br /&gt;
		end&lt;br /&gt;
		local moduleList = mList.makeList(&#039;bulleted&#039;, moduleLinks)&lt;br /&gt;
		boxArgs.text = format(&#039;header&#039;) .. &#039;\n&#039; .. moduleList&lt;br /&gt;
	end&lt;br /&gt;
	boxArgs.type = &#039;notice&#039;&lt;br /&gt;
	boxArgs.small = true&lt;br /&gt;
	boxArgs.image = string.format(&lt;br /&gt;
		&#039;[[File:Lua-logo-nolabel.svg|30px|alt=%s|link=%s]]&#039;,&lt;br /&gt;
		format(&#039;logo_alt&#039;),&lt;br /&gt;
		format(&#039;logo_link&#039;)&lt;br /&gt;
	)&lt;br /&gt;
	return mMessageBox.main(&#039;mbox&#039;, boxArgs)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderTrackingCategories(args, modules, titleObj, cfg)&lt;br /&gt;
	if yesno(args.nocat) then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	cfg = cfg or getConfig()&lt;br /&gt;
	&lt;br /&gt;
	local cats = {}&lt;br /&gt;
	&lt;br /&gt;
	-- Error category&lt;br /&gt;
	if #modules &amp;lt; 1 and not (cfg[&#039;allow_wishes&#039;] or yesno(args.wish)) and cfg[&#039;error_category&#039;] then&lt;br /&gt;
		cats[#cats + 1] = cfg[&#039;error_category&#039;]&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Lua templates category&lt;br /&gt;
	titleObj = titleObj or mw.title.getCurrentTitle()&lt;br /&gt;
	if titleObj.namespace == 10 &lt;br /&gt;
		and not cfg[&#039;subpage_blacklist&#039;][titleObj.subpageText]&lt;br /&gt;
	then&lt;br /&gt;
		local category = args.category&lt;br /&gt;
		if not category then&lt;br /&gt;
			local pagename = modules[1] and mw.title.new(modules[1])&lt;br /&gt;
			category = pagename and cfg[&#039;module_categories&#039;][pagename.text]&lt;br /&gt;
			if not category then&lt;br /&gt;
				if (cfg[&#039;allow_wishes&#039;] or yesno(args.wish)) and #modules &amp;lt; 1 then&lt;br /&gt;
					category = cfg[&#039;wish_category&#039;]&lt;br /&gt;
				else&lt;br /&gt;
					category = cfg[&#039;default_category&#039;]&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if category then&lt;br /&gt;
			cats[#cats + 1] = category&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	for i, cat in ipairs(cats) do&lt;br /&gt;
		cats[i] = string.format(&#039;[[Category:%s]]&#039;, cat)&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat(cats)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Message_box/configuration/doc/en&amp;diff=1702</id>
		<title>Module:Message box/configuration/doc/en</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Message_box/configuration/doc/en&amp;diff=1702"/>
		<updated>2024-01-05T16:55:23Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#ifeq:{{SUBPAGENAME}}|doc||{{Documentation subpage}}}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;!--&lt;br /&gt;
--&amp;gt;&amp;lt;/noinclude&amp;gt;{{#switch:&lt;br /&gt;
| =&lt;br /&gt;
&amp;lt;includeonly&amp;gt;{{Languages|Module:Message box/configuration/doc}}&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
&amp;lt;!-- Add categories where indicated at the bottom of this page and interwikis at Wikidata --&amp;gt;&lt;br /&gt;
{{Used in system}}&lt;br /&gt;
{{Module rating|protected}}&lt;br /&gt;
This module contains configuration data for [[Module:Message box]].&lt;br /&gt;
&lt;br /&gt;
== Configuration options ==&lt;br /&gt;
{{(!}} class=&amp;quot;wikitable plainrowheaders&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; {{!}} Option&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; {{!}} Explanation&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;types&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} A table containing data used by the type parameter of the message box. The table keys are the values that can be passed to the type parameter, and the table values are tables containing the class and the image used by that type.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;default&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} The type to use if no value was passed to the type parameter, or if an invalid value was specified.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;showInvalidTypeError&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} Whether to show an error if the value passed to the type parameter was invalid.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;allowBlankParams&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} Usually blank values are stripped from parameters passed to the module. However, whitespace is preserved for the parameters included in the &amp;lt;code&amp;gt;allowBlankParams&amp;lt;/code&amp;gt; table.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;allowSmall&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} Whether a small version of the message box can be produced with {{para|small|1}}.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;smallParam&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} A custom value for the {{para|small}} parameter. For example, if set to {{inline-code|lang=lua|&amp;quot;left&amp;quot;}} you can produce a small message box using {{para|small|left}}.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;smallClass&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} The class to use for small message boxes.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;substCheck&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} Whether to perform a subst check or not.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;classes&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} An array of classes to use with the message box.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;imageEmptyCell&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} Whether to use an empty {{tag|td}} cell if there is no image set. This is used to preserve spacing for message boxes with a width of less than 100% of the screen.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;imageEmptyCellStyle&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} Whether empty image cells should be styled.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;imageCheckBlank&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} Whether {{para|image|blank}} results in no image being displayed.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;imageSmallSize&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} Usually, images used in small message boxes are set to 30x30px. This sets a custom size.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;imageCellDiv&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} Whether to enclose the image in a {{tag|div|o}} enforcing a maximum image size.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;useCollapsibleTextFields&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} Whether to use text fields that can be collapsed, i.e. {{inline-code|lang=lua|&amp;quot;issue&amp;quot;}}, {{inline-code|lang=lua|&amp;quot;fix&amp;quot;}}, {{inline-code|lang=lua|&amp;quot;talk&amp;quot;}}, etc. Currently only used in {{tlx|ambox}}.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;imageRightNone&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} Whether {{para|imageright|none}} results in no image being displayed on the right-hand side of the message box.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;sectionDefault&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} The default name for the {{para|section}} parameter. Depends on &amp;lt;code&amp;gt;useCollapsibleTextFields&amp;lt;/code&amp;gt;.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;allowMainspaceCategories&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} Allow categorisation in the main namespace.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;templateCategory&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} The name of a category to be placed on the template page.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;templateCategoryRequireName&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} Whether the {{para|name}} parameter is required to display the template category.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;templateErrorCategory&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} The name of the error category to be used on the template page.&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;templateErrorParamsToCheck&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} An array of parameter names to check. If any are absent, the &amp;lt;code&amp;gt;templateErrorCategory&amp;lt;/code&amp;gt; is applied to the template page.&lt;br /&gt;
{{!)}}&lt;br /&gt;
&amp;lt;includeonly&amp;gt;{{Sandbox other||&lt;br /&gt;
&amp;lt;!-- Categories below this line; interwikis at Wikidata --&amp;gt;&lt;br /&gt;
[[Category:Modules]]&lt;br /&gt;
}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Module documentation pages{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
| #default=&lt;br /&gt;
  {{#invoke:Template translation|renderTranslatedTemplate|template=Module:Message box/configuration/doc|noshift=1|uselang={{int:lang}}}}&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Message_box/configuration/doc&amp;diff=1700</id>
		<title>Module:Message box/configuration/doc</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Module:Message_box/configuration/doc&amp;diff=1700"/>
		<updated>2024-01-05T16:55:19Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#ifeq:{{SUBPAGENAME}}|doc||{{Documentation subpage}}}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;!--&lt;br /&gt;
--&amp;gt;&amp;lt;/noinclude&amp;gt;{{#switch:&amp;lt;translate&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
| =&lt;br /&gt;
&amp;lt;includeonly&amp;gt;{{Languages|Module:Message box/configuration/doc}}&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
&amp;lt;!-- Add categories where indicated at the bottom of this page and interwikis at Wikidata --&amp;gt;&lt;br /&gt;
{{Used in system}}&lt;br /&gt;
{{Module rating|protected}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
This module contains configuration data for &amp;lt;tvar name=1&amp;gt;[[Module:Message box]]&amp;lt;/tvar&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Configuration options == &amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{(!}} class=&amp;quot;wikitable plainrowheaders&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; {{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt; Option&amp;lt;/translate&amp;gt;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; {{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:4--&amp;gt; Explanation&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;types&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt; A table containing data used by the type parameter of the message box.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt; The table keys are the values that can be passed to the type parameter, and the table values are tables containing the class and the image used by that type.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;default&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt; The type to use if no value was passed to the type parameter, or if an invalid value was specified.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;showInvalidTypeError&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt; Whether to show an error if the value passed to the type parameter was invalid.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;allowBlankParams&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:9--&amp;gt; Usually blank values are stripped from parameters passed to the module.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:10--&amp;gt; However, whitespace is preserved for the parameters included in the &amp;lt;tvar name=1&amp;gt;&amp;lt;code&amp;gt;allowBlankParams&amp;lt;/code&amp;gt;&amp;lt;/tvar&amp;gt; table.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;allowSmall&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt; Whether a small version of the message box can be produced with &amp;lt;tvar name=1&amp;gt;{{para|small|1}}&amp;lt;/tvar&amp;gt;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;smallParam&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:12--&amp;gt; A custom value for the &amp;lt;tvar name=1&amp;gt;{{para|small}}&amp;lt;/tvar&amp;gt; parameter.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt; For example, if set to &amp;lt;tvar name=1&amp;gt;{{inline-code|lang=lua|&amp;quot;left&amp;quot;}}&amp;lt;/tvar&amp;gt; you can produce a small message box using &amp;lt;tvar name=2&amp;gt;{{para|small|left}}&amp;lt;/tvar&amp;gt;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;smallClass&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt; The class to use for small message boxes.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;substCheck&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:15--&amp;gt; Whether to perform a subst check or not.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;classes&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt; An array of classes to use with the message box.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;imageEmptyCell&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:17--&amp;gt; Whether to use an empty &amp;lt;tvar name=1&amp;gt;{{tag|td}}&amp;lt;/tvar&amp;gt; cell if there is no image set.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:18--&amp;gt; This is used to preserve spacing for message boxes with a width of less than &amp;lt;tvar name=1&amp;gt;100%&amp;lt;/tvar&amp;gt; of the screen.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;imageEmptyCellStyle&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:19--&amp;gt; Whether empty image cells should be styled.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;imageCheckBlank&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt; Whether &amp;lt;tvar name=1&amp;gt;{{para|image|blank}}&amp;lt;/tvar&amp;gt; results in no image being displayed.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;imageSmallSize&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:21--&amp;gt; Usually, images used in small message boxes are set to &amp;lt;tvar name=1&amp;gt;30x30px&amp;lt;/tvar&amp;gt;.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:22--&amp;gt; This sets a custom size.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;imageCellDiv&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:23--&amp;gt; Whether to enclose the image in a &amp;lt;tvar name=1&amp;gt;{{tag|div|o}}&amp;lt;/tvar&amp;gt; enforcing a maximum image size.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;useCollapsibleTextFields&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt; Whether to use text fields that can be collapsed, i.e. &amp;lt;tvar name=1&amp;gt;{{inline-code|lang=lua|&amp;quot;issue&amp;quot;}}&amp;lt;/tvar&amp;gt;, &amp;lt;tvar name=2&amp;gt;{{inline-code|lang=lua|&amp;quot;fix&amp;quot;}}&amp;lt;/tvar&amp;gt;, &amp;lt;tvar name=3&amp;gt;{{inline-code|lang=lua|&amp;quot;talk&amp;quot;}}&amp;lt;/tvar&amp;gt;, etc.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:25--&amp;gt; Currently only used in &amp;lt;tvar name=1&amp;gt;{{tlx|ambox}}&amp;lt;/tvar&amp;gt;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;imageRightNone&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:26--&amp;gt; Whether &amp;lt;tvar name=1&amp;gt;{{para|imageright|none}}&amp;lt;/tvar&amp;gt; results in no image being displayed on the right-hand side of the message box.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;sectionDefault&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:27--&amp;gt; The default name for the &amp;lt;tvar name=1&amp;gt;{{para|section}}&amp;lt;/tvar&amp;gt; parameter.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:28--&amp;gt; Depends on &amp;lt;tvar name=1&amp;gt;&amp;lt;code&amp;gt;useCollapsibleTextFields&amp;lt;/code&amp;gt;&amp;lt;/tvar&amp;gt;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;allowMainspaceCategories&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt; Allow categorisation in the main namespace.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;templateCategory&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:30--&amp;gt; The name of a category to be placed on the template page.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;templateCategoryRequireName&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:31--&amp;gt; Whether the &amp;lt;tvar name=1&amp;gt;{{para|name}}&amp;lt;/tvar&amp;gt; parameter is required to display the template category.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;templateErrorCategory&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt; The name of the error category to be used on the template page.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left;font-weight:normal&amp;quot; {{!}} &amp;lt;code&amp;gt;templateErrorParamsToCheck&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:33--&amp;gt; An array of parameter names to check.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:34--&amp;gt; If any are absent, the &amp;lt;tvar name=1&amp;gt;&amp;lt;code&amp;gt;templateErrorCategory&amp;lt;/code&amp;gt;&amp;lt;/tvar&amp;gt; is applied to the template page.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!)}}&lt;br /&gt;
&amp;lt;includeonly&amp;gt;{{Sandbox other||&lt;br /&gt;
&amp;lt;!-- Categories below this line; interwikis at Wikidata --&amp;gt;&lt;br /&gt;
[[Category:Modules]]&lt;br /&gt;
}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Module documentation pages{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
| #default=&lt;br /&gt;
  {{#invoke:Template translation|renderTranslatedTemplate|template=Module:Message box/configuration/doc|noshift=1|uselang={{int:lang}}}}&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:Module_rating/en&amp;diff=1698</id>
		<title>Template:Module rating/en</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:Module_rating/en&amp;diff=1698"/>
		<updated>2024-01-05T16:55:15Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;{{Module other|{{ombox&lt;br /&gt;
 | type      = notice&lt;br /&gt;
 | image     = {{#switch: {{{1|}}}&lt;br /&gt;
   | pre-alpha | prealpha | pa = [[File:OOjs UI icon text-style.svg|40x40px|link=]]&lt;br /&gt;
   | alpha | a                 = [[File:OOjs UI icon bold-a.svg|40x40px|link=]]&lt;br /&gt;
   | beta | b                  = [[File:OOjs UI icon bold-b.svg|40x40px|link=]]&lt;br /&gt;
   | release | r | general | g = [[File:OOjs UI icon check-constructive.svg|40x40px|link=]]&lt;br /&gt;
   | protected | protect | p   = [[File:{{#if:{{CASCADINGSOURCES:{{FULLPAGENAME}}}}|Cascade-protection-shackle.svg|{{#ifeq:{{PROTECTIONLEVEL:edit}}|sysop|Full-protection-shackle-red.svg|Semi-protection-shackle-no-text.svg}}}}|40x40px|link=]]&lt;br /&gt;
   | semiprotected | semiprotect | semi = [[File:Semi-protection-shackle.svg|40x40px|link=]]&lt;br /&gt;
   | #default = [[File:OOjs UI icon alert-destructive.svg|40x40px|link=]]&lt;br /&gt;
  }}&lt;br /&gt;
 | style     = &lt;br /&gt;
 | textstyle = &lt;br /&gt;
 | text      = {{#switch: {{{1|}}}&lt;br /&gt;
   | pre-alpha | prealpha | pa = This module is rated as [[Special:MyLanguage/Category:Modules in pre-alpha development|pre-alpha]]. It is unfinished, and may or may not be in active development. It should not be used from article namespace pages. Modules remain pre-alpha until the original editor (or someone who takes one over if it is abandoned for some time) is satisfied with the basic structure.&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#ifexpr:&lt;br /&gt;
         &amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
         {{IsDocSubpage|false=0}} or {{#ifeq:{{SUBPAGENAME}}|sandbox|1|0}}&lt;br /&gt;
       || {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules in pre-alpha development|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | alpha | a                 = This module is rated as [[Special:MyLanguage/Category:Modules in alpha|alpha]]. It is ready for third party input, and may be used on a few pages to see if problems arise, but should be watched. Suggestions for new features or changes in their input and output mechanisms are welcome.&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#ifexpr:&lt;br /&gt;
         &amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
         {{IsDocSubpage|false=0}} or {{#ifeq:{{SUBPAGENAME}}|sandbox|1|0}}&lt;br /&gt;
       || {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules in alpha|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | beta | b                  = This module is rated as [[Special:MyLanguage/Category:Modules in beta|beta]], and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected.&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#ifexpr:&lt;br /&gt;
         &amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
         {{IsDocSubpage|false=0}} or {{#ifeq:{{SUBPAGENAME}}|sandbox|1|0}}&lt;br /&gt;
       || {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules in beta|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | release | r | general | g = This module is rated as [[Special:MyLanguage/Category:Modules for general use|ready for general use]]. It has reached a mature form and is thought to be bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other resources as an option for new users to learn. To reduce server load and bad output, it should be improved by [[w:WP:TESTCASES|sandbox testing]] rather than repeated trial-and-error editing.&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#ifexpr:&lt;br /&gt;
         &amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
         {{IsDocSubpage|false=0}} or {{#ifeq:{{SUBPAGENAME}}|sandbox|1|0}}&lt;br /&gt;
       || {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules for general use|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | protected | protect | p   = This module is [[Special:MyLanguage/Category:Modules subject to page protection|subject to {{#if:{{CASCADINGSOURCES:{{FULLPAGENAME}}}}|cascading|page}} protection]]. It is a highly visible module in use by a very large number of pages. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is [[Special:MyLanguage/Project:Protected page|protected]] from editing.&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#ifexpr:&lt;br /&gt;
         &amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
         {{IsDocSubpage|false=0}} or {{#ifeq:{{SUBPAGENAME}}|sandbox|1|0}}&lt;br /&gt;
       || {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules subject to page protection|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | #default                  = {{error|1=Module rating is invalid or not specified.}}&lt;br /&gt;
  }}&lt;br /&gt;
}}|{{error|1=Error: {{tl|Module rating}} must be placed in the Module namespace.}}|demospace={{{demospace|&amp;lt;noinclude&amp;gt;module&amp;lt;/noinclude&amp;gt;}}}}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation|content=&lt;br /&gt;
&lt;br /&gt;
This template is used to rate [[Lua/Overview|Lua modules]] by quality.&lt;br /&gt;
It is placed at the top of the module&#039;s /doc subpage.&lt;br /&gt;
It produces a message informing users about the rating system, and it also places the module into a tracking category.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
&lt;br /&gt;
Basic usage:&lt;br /&gt;
{{pre|{{tlx|module rating|&#039;&#039;rating&#039;&#039;}}}}&lt;br /&gt;
&lt;br /&gt;
Without categories:&lt;br /&gt;
{{pre|{{tlx|module rating|&#039;&#039;rating&#039;&#039;|3=nocat=true}}}}&lt;br /&gt;
&lt;br /&gt;
If {{tlx|Module rating}} is used outside the Module namespace, an error message is shown: {{module rating}}&lt;br /&gt;
&lt;br /&gt;
== Ratings ==&lt;br /&gt;
The rating should be placed in the first positional parameter.&lt;br /&gt;
There are five different ratings: &#039;&#039;&#039;pre-alpha&#039;&#039;&#039;{{int|comma-separator}}&#039;&#039;&#039;alpha&#039;&#039;&#039;{{int|comma-separator}}&#039;&#039;&#039;beta&#039;&#039;&#039;{{int|comma-separator}}&#039;&#039;&#039;release&#039;&#039;&#039;{{int|and}}{{int|word-separator}}&#039;&#039;&#039;protected&#039;&#039;&#039;.&lt;br /&gt;
There are also short alias codes for each of the ratings.&lt;br /&gt;
&lt;br /&gt;
{{(!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Rating&lt;br /&gt;
! Aliases&lt;br /&gt;
! Result&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;pre-alpha&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;prealpha&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} {{module rating|pre-alpha|nocat=true|demospace=Module}}&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;alpha&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} {{module rating|alpha|nocat=true|demospace=module}}&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;beta&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} {{module rating|beta|nocat=true|demospace=module}}&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;release&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;r&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;general&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;g&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} {{module rating|release|nocat=true|demospace=module}}&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;protected&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;protect&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} {{module rating|protected|nocat=true|demospace=module}}&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} &#039;&#039;Anything else or if missing&#039;&#039;&lt;br /&gt;
{{!}}&lt;br /&gt;
{{!}} {{module rating|prdaskidkated|nocat=true|demospace=module}}&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!)}}&lt;br /&gt;
&lt;br /&gt;
== TemplateData ==&lt;br /&gt;
{{Module rating/doc}}&lt;br /&gt;
&lt;br /&gt;
== Categories ==&lt;br /&gt;
&lt;br /&gt;
The template will put modules in one of the following categories, according to the rating specified:&lt;br /&gt;
&lt;br /&gt;
* {{ll|Category:Modules in pre-alpha development}}&lt;br /&gt;
* {{ll|Category:Modules in alpha}}&lt;br /&gt;
* {{ll|Category:Modules in beta}}&lt;br /&gt;
* {{ll|Category:Modules for general use}}&lt;br /&gt;
* {{ll|Category:Modules subject to page protection}}&lt;br /&gt;
&lt;br /&gt;
These categories are suppressed on pages ending with /doc.&lt;br /&gt;
To suppress categories on all pages, you can use the code {{para|nocat|true}}.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* {{tl|module-rating categories}}&lt;br /&gt;
* [[Lua]]&lt;br /&gt;
* {{tl|Lua}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
	<entry>
		<id>https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:Module_rating&amp;diff=1696</id>
		<title>Template:Module rating</title>
		<link rel="alternate" type="text/html" href="https://wiki.fairwayfarmsswimclub.com/index.php?title=Template:Module_rating&amp;diff=1696"/>
		<updated>2024-01-05T16:55:14Z</updated>

		<summary type="html">&lt;p&gt;Matt Parnell: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;{{Module other|{{ombox&lt;br /&gt;
 | type      = notice&lt;br /&gt;
 | image     = {{#switch: {{{1|}}}&lt;br /&gt;
   | pre-alpha | prealpha | pa = [[File:OOjs UI icon text-style.svg|40x40px|link=]]&lt;br /&gt;
   | alpha | a                 = [[File:OOjs UI icon bold-a.svg|40x40px|link=]]&lt;br /&gt;
   | beta | b                  = [[File:OOjs UI icon bold-b.svg|40x40px|link=]]&lt;br /&gt;
   | release | r | general | g = [[File:OOjs UI icon check-constructive.svg|40x40px|link=]]&lt;br /&gt;
   | protected | protect | p   = [[File:{{#if:{{CASCADINGSOURCES:{{FULLPAGENAME}}}}|Cascade-protection-shackle.svg|{{#ifeq:{{PROTECTIONLEVEL:edit}}|sysop|Full-protection-shackle-red.svg|Semi-protection-shackle-no-text.svg}}}}|40x40px|link=]]&lt;br /&gt;
   | semiprotected | semiprotect | semi = [[File:Semi-protection-shackle.svg|40x40px|link=]]&lt;br /&gt;
   | #default = [[File:OOjs UI icon alert-destructive.svg|40x40px|link=]]&lt;br /&gt;
  }}&lt;br /&gt;
 | style     = &lt;br /&gt;
 | textstyle = &lt;br /&gt;
 | text      = {{#switch: {{{1|}}}&lt;br /&gt;
   | pre-alpha | prealpha | pa = &amp;lt;translate&amp;gt;&amp;lt;!--T:1--&amp;gt; This module is rated as [[&amp;lt;tvar name=1&amp;gt;Special:MyLanguage/Category:Modules in pre-alpha development&amp;lt;/tvar&amp;gt;|pre-alpha]].&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:2--&amp;gt; It is unfinished, and may or may not be in active development.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt; It should not be used from article namespace pages.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:4--&amp;gt; Modules remain pre-alpha until the original editor (or someone who takes one over if it is abandoned for some time) is satisfied with the basic structure.&amp;lt;/translate&amp;gt;&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#ifexpr:&lt;br /&gt;
         &amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
         {{IsDocSubpage|false=0}} or {{#ifeq:{{SUBPAGENAME}}|sandbox|1|0}}&lt;br /&gt;
       || {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules in pre-alpha development|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | alpha | a                 = &amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt; This module is rated as [[&amp;lt;tvar name=1&amp;gt;Special:MyLanguage/Category:Modules in alpha&amp;lt;/tvar&amp;gt;|alpha]].&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:21--&amp;gt; It is ready for third party input, and may be used on a few pages to see if problems arise, but should be watched.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:22--&amp;gt; Suggestions for new features or changes in their input and output mechanisms are welcome.&amp;lt;/translate&amp;gt;&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#ifexpr:&lt;br /&gt;
         &amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
         {{IsDocSubpage|false=0}} or {{#ifeq:{{SUBPAGENAME}}|sandbox|1|0}}&lt;br /&gt;
       || {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules in alpha|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | beta | b                  = &amp;lt;translate&amp;gt;&amp;lt;!--T:23--&amp;gt; This module is rated as [[&amp;lt;tvar name=1&amp;gt;Special:MyLanguage/Category:Modules in beta&amp;lt;/tvar&amp;gt;|beta]], and is ready for widespread use.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt; It is still new and should be used with some caution to ensure the results are as expected.&amp;lt;/translate&amp;gt;&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#ifexpr:&lt;br /&gt;
         &amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
         {{IsDocSubpage|false=0}} or {{#ifeq:{{SUBPAGENAME}}|sandbox|1|0}}&lt;br /&gt;
       || {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules in beta|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | release | r | general | g = &amp;lt;translate&amp;gt;&amp;lt;!--T:25--&amp;gt; This module is rated as [[&amp;lt;tvar name=1&amp;gt;Special:MyLanguage/Category:Modules for general use&amp;lt;/tvar&amp;gt;|ready for general use]].&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:26--&amp;gt; It has reached a mature form and is thought to be bug-free and ready for use wherever appropriate.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:27--&amp;gt; It is ready to mention on help pages and other resources as an option for new users to learn.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:28--&amp;gt; To reduce server load and bad output, it should be improved by [[w:WP:TESTCASES|sandbox testing]] rather than repeated trial-and-error editing.&amp;lt;/translate&amp;gt;&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#ifexpr:&lt;br /&gt;
         &amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
         {{IsDocSubpage|false=0}} or {{#ifeq:{{SUBPAGENAME}}|sandbox|1|0}}&lt;br /&gt;
       || {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules for general use|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | protected | protect | p   = &amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt; This module is [[&amp;lt;tvar name=1&amp;gt;Special:MyLanguage/Category:Modules subject to page protection&amp;lt;/tvar&amp;gt;|subject to {{&amp;lt;tvar name=2&amp;gt;#if:{{CASCADINGSOURCES:{{FULLPAGENAME}}}}&amp;lt;/tvar&amp;gt;|cascading|page}} protection]].&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:30--&amp;gt; It is a highly visible module in use by a very large number of pages.&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:31--&amp;gt; Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is [[&amp;lt;tvar name=1&amp;gt;Special:MyLanguage/Project:Protected page&amp;lt;/tvar&amp;gt;|protected]] from editing.&amp;lt;/translate&amp;gt;&amp;lt;!--&lt;br /&gt;
   --&amp;gt;{{#ifexpr:&lt;br /&gt;
         &amp;lt;!-- No category for /doc or /sandbox subpages --&amp;gt;&lt;br /&gt;
         {{IsDocSubpage|false=0}} or {{#ifeq:{{SUBPAGENAME}}|sandbox|1|0}}&lt;br /&gt;
       || {{#ifeq: {{{nocat|}}} | true | &amp;lt;!-- No category if user sets nocat=true --&amp;gt; | [[Category:Modules subject to page protection|{{PAGENAME}}]] }}&lt;br /&gt;
      }}&lt;br /&gt;
   | #default                  = {{error|1=&amp;lt;translate&amp;gt;&amp;lt;!--T:17--&amp;gt; Module rating is invalid or not specified.&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
  }}&lt;br /&gt;
}}|{{error|1=&amp;lt;translate&amp;gt;&amp;lt;!--T:18--&amp;gt; Error:&amp;lt;/translate&amp;gt; &amp;lt;translate&amp;gt;&amp;lt;!--T:19--&amp;gt; &amp;lt;tvar name=1&amp;gt;{{tl|Module rating}}&amp;lt;/tvar&amp;gt; must be placed in the Module namespace.&amp;lt;/translate&amp;gt;}}|demospace={{{demospace|&amp;lt;noinclude&amp;gt;module&amp;lt;/noinclude&amp;gt;}}}}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation|content=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt; This template is used to rate [[Lua/Overview|Lua modules]] by quality.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt; It is placed at the top of the module&#039;s /doc subpage.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt; It produces a message informing users about the rating system, and it also places the module into a tracking category.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Usage == &amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
Basic usage:&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{pre|{{tlx|module rating|&#039;&#039;rating&#039;&#039;}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:10--&amp;gt; Without categories:&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{pre|{{tlx|module rating|&#039;&#039;rating&#039;&#039;|3=nocat=true}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt; If &amp;lt;tvar name=1&amp;gt;{{tlx|Module rating}}&amp;lt;/tvar&amp;gt; is used outside the Module namespace, an error message is shown: &amp;lt;tvar name=2&amp;gt;{{module rating}}&amp;lt;/tvar&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Ratings == &amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:33--&amp;gt; The rating should be placed in the first positional parameter.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:34--&amp;gt; There are five different ratings: &amp;lt;tvar name=1&amp;gt;&#039;&#039;&#039;pre-alpha&#039;&#039;&#039;{{int|comma-separator}}&#039;&#039;&#039;alpha&#039;&#039;&#039;{{int|comma-separator}}&#039;&#039;&#039;beta&#039;&#039;&#039;{{int|comma-separator}}&#039;&#039;&#039;release&#039;&#039;&#039;{{int|and}}{{int|word-separator}}&#039;&#039;&#039;protected&#039;&#039;&#039;&amp;lt;/tvar&amp;gt;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:35--&amp;gt; There are also short alias codes for each of the ratings.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{(!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;translate&amp;gt;&amp;lt;!--T:12--&amp;gt; Rating&amp;lt;/translate&amp;gt;&lt;br /&gt;
! &amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt; Aliases&amp;lt;/translate&amp;gt;&lt;br /&gt;
! &amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt; Result&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;pre-alpha&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;prealpha&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} {{module rating|pre-alpha|nocat=true|demospace=Module}}&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;alpha&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} {{module rating|alpha|nocat=true|demospace=module}}&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;beta&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} {{module rating|beta|nocat=true|demospace=module}}&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;release&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;r&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;general&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;g&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} {{module rating|release|nocat=true|demospace=module}}&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;protected&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} &amp;lt;code&amp;gt;protect&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;&lt;br /&gt;
{{!}} {{module rating|protected|nocat=true|demospace=module}}&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} &amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt; &#039;&#039;Anything else or if missing&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{!}}&lt;br /&gt;
{{!}} {{module rating|prdaskidkated|nocat=true|demospace=module}}&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!)}}&lt;br /&gt;
&lt;br /&gt;
== TemplateData ==&lt;br /&gt;
{{Module rating/doc}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Categories == &amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
The template will put modules in one of the following categories, according to the rating specified:&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* {{ll|Category:Modules in pre-alpha development}}&lt;br /&gt;
* {{ll|Category:Modules in alpha}}&lt;br /&gt;
* {{ll|Category:Modules in beta}}&lt;br /&gt;
* {{ll|Category:Modules for general use}}&lt;br /&gt;
* {{ll|Category:Modules subject to page protection}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:38--&amp;gt; These categories are suppressed on pages ending with /doc.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:39--&amp;gt; To suppress categories on all pages, you can use the code &amp;lt;tvar name=1&amp;gt;{{para|nocat|true}}&amp;lt;/tvar&amp;gt;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== See also == &amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* {{tl|module-rating categories}}&lt;br /&gt;
* [[Lua]]&lt;br /&gt;
* {{tl|Lua}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Matt Parnell</name></author>
	</entry>
</feed>