ASP 페이지에서 Microsoft® COM(Component Object Model) 구성 요소를 사용하여 ASP의 기존 기능을 확장할 수 있습니다. COM 구성 요소는 ASP 페이지에서 호출할 수 있는 컴파일된 코드입니다. COM 구성 요소는 안전하고 간단하며 다시 사용할 수 있는 DLL로 컴파일된 개체이며 Microsoft Visual C++®, Microsoft Visual Basic® 또는 COM을 지원하는 모든 언어로 작성할 수 있습니다. 예를 들어, 이 자습서 모듈 1에서 사용된 ADO(Microsoft ActiveX® Data Objects)의 메서드와 속성을 통해 효과적으로 데이터베이스를 쿼리할 수 있습니다. ADO 개체는 COM 구성 요소로 만들어졌기 때문에, ADO를 사용하면 복잡한 데이터 액세스 코드를 직접 쓸 필요가 없습니다.
이 모듈에서는 ASP에 있는 COM 구성 요소를 사용하며 직접 쓸 수도 있습니다. 이 모듈에서는 전자 상거래에 유용한 서비스를 배달하는 ASP 페이지를 개발하는 방법을 보여주며 다음 단원으로 구성되어 있습니다.
광고는 비중 있는 웹 비즈니스입니다. 이 단원에서는 웹 페이지에서 광고를 회전시키기 위해 IIS에 설치한 Ad Rotator 구성 요소 사용법을 설명합니다. Ad Rotator 구성 요소는 사용자가 웹 페이지를 로드하거나 새로 고칠 때마다 웹 페이지의 광고를 선택합니다. 또한 광고가 있는 ASP 파일을 모두 변경하지 않고도 리디렉션 파일과 순환 일정 파일을 변경하여 광고를 변경할 수 있습니다. 따라서 웹 사이트에서 여러 페이지에 광고를 게시하는 경우 개발 시간을 절약할 수 있습니다.
Ad Rotator 구성 요소를 설정하려면 광고의 URL 링크가 있는 리디렉션 파일과 디스플레이 데이터가 있는 순환 일정 파일이 필요합니다. 이 두 파일을 설정하면 웹 사이트의 모든 ASP 페이지가 Ad Rotator 구성 요소를 호출할 수 있습니다.
이 단원에서는 다음 작업을 수행합니다.
순환 일정 파일은 광고를 클릭한 후의 리디렉션 정보, 표시된 광고의 크기, 표시할 이미지, 광고에 대한 설명, 특정 광고가 선택되는 빈도를 나타내는 숫자 등을 비롯하여, 표시할 광고에 대한 정보를 카탈로그하는 데 사용됩니다. Ad Rotator 구성 요소의 메서드가 ASP 페이지에서 호출되면 구성 요소는 이 파일을 사용하여 표시할 광고를 선택합니다.
순환 일정 파일은 별표(*)로 구분되는 두 섹션으로 나누어집니다. 첫 번째 섹션에는 모든 광고의 공통 정보가 있으며, 두 번째 섹션에는 각 광고별 특정 데이터가 있습니다. Microsoft.com에 있는 이미지 몇 개를 광고 이미지로 사용하여 순환 일정 파일을 테스트하십시오. 다음 목록은 순환 일정 파일의 구조에 대해 간단히 설명합니다.
각 광고에 대해 다음을 완료해야 합니다.
다음 코드를 복사하여 텍스트 편집기에 붙여 넣고 x:\Inetpub\Wwwroot\Tutorial 디렉터리에 파일을 MyAdRot.txt로 저장합니다.
REDIRECT AdRotRedirect.asp
WIDTH 250
HEIGHT 60
BORDER 0
*
http://www.microsoft.com/windows/images/bnrWinfam.gif
http://www.microsoft.com/windows
Microsoft Windows
2
http://www.microsoft.com/office/images/office_logo.gif
http://www.microsoft.com/office
Office 2000
3
사용자가 광고를 클릭하면 ASP에서 쓰여진 Ad Rotator 리디렉션 파일이 광고를 표시하기 전에 일부 정보를 캡처하여 파일에 쓸 수 있습니다. \par
이 작업을 수행하려면 x:\InetPub\Wwwroot\Tutorial 폴더는 IUSR_ComputerName 및 IWAM_ComputerName 계정에 읽기/쓰기 액세스를 주어야 합니다. 또는 이 자습서의 모듈 1의 단원 3에서 코드를 사용하여 Microsoft Access 데이터베이스에 이 정보를 쓸 수도 있습니다.
다음 코드를 복사하여 텍스트 편집기에 붙여넣고 x:\Inetpub\Wwwroot\Tutorial 디렉터리에 파일을 AdRotRedirect.asp로 저장합니다.
<%@ Language=VBScript %>
<html>
<head>
<title>AdRotRedirect file</title>
</head>
<body>
<%
'Create some variables.
dim strLogFile
'Get the physical path of this Web directory so that we know the path exists.
'The ASP Server object has many useful methods.
strLogFile = Server.MapPath(".") & "\AdRotLog.txt"
'Set some constants for working with files.
Const cForAppending = 8
Const cTristateUseDefault = -2
'Create a FileSystemObject object,
' which gives you access to files and folders on the system.
Set fsoObject = Server.CreateObject("Scripting.FileSystemObject")
'Open a handle to the file.
'True means that the file will be created if it doesn't already exist.
Set tsObject = fsoObject.OpenTextFile(strLogFile, cForAppending, True)
'Record the data for the user who has just clicked on an advertisement.
'We have used the Write method of the ASP Request object.
'The ServerVariables collection of the ASP Request object holds vast
' amounts of data for each request made to a Web server.
tsObject.WriteLine "--------------------"
tsObject.WriteLine Date & ", " & Time
tsObject.WriteLine Request.ServerVariables("LOGON_USER")
tsObject.WriteLine Request.ServerVariables("REMOTE_ADDR")
tsObject.WriteLine Request.QueryString("url")
tsObject.WriteLine Request.ServerVariables("HTTP_REFERER")
tsObject.WriteLine Request.ServerVariables("HTTP_USER_AGENT")
tsObject.Close
'Redirect to the Advertiser's Web site using the Redirect method
' of the ASP Response object.
'When the AdRotator component calls AdRotRedirect.asp, it
' automatically passes in the advertiser's URL in the QueryString.
Response.Redirect Request.QueryString("url")
%>
</body>
</html>
\par
포함 파일은 두 개 이상의 ASP 파일이나 HTML 파일이 사용하는 모든 코드를 저장하는 데 사용됩니다. 포함 파일에 있는 간단한 함수에 Ad Rotator 코드를 넣는 경우 적합합니다. Ad Rotator 포함 파일을 사용하려면 광고를 표시하려면 ASP 또는 HTML 파일에서 함수 호출을 하나만 만들어야 합니다. 또는 광고를 표시할 모든 ASP 파일에 있는 포함 파일에서 코드를 넣을 수도 있습니다. 그러나 코드를 변경하려면 포함 파일 하나가 아니라 모든 ASP 파일에서 변경해야 합니다.
이 예제에서는 GetAd라는 함수가 있는 Ad Rotator 포함 파일을 만듭니다. 이 함수는 광고를 임의로 선택하여 ASP 페이지에 표시합니다.
다음 코드를 복사하여 텍스트 편집기에 붙여넣고 x:\Inetpub\Wwwroot\Tutorial 디렉터리에 파일을 AdRotatorLogic.inc로 저장합니다.
<%
Function GetAd()
dim objLoad
'Create an instance of the AdRotator component.
Set objLoad = Server.CreateObject("MSWC.AdRotator")
'Set the TargetFrame property, if any. If you have a Web
' page using frames, this is the frame where the URL opens.
'If the HTML page does not find the TARGET name,
' the URL will be opened in a new window.
objLoad.TargetFrame = "TARGET=new"
'Set one of the other AdRotator properties.
objLoad.Border = 1
'Get a random advertisement from the text file.
GetAd = objLoad.GetAdvertisement("MyAdRot.txt")
End Function
%>
Ad Rotator 구성 요소로 만든 응용 프로그램을 테스트하려면, 만든 Ad Rotator 포함 파일의 함수를 호출하는 ASP 페이지가 필요합니다.
다음 코드를 복사하여 텍스트 편집기에 붙여넣고 x:\Inetpub\Wwwroot\Tutorial 디렉터리에 파일을 DisplayAds.asp로 저장합니다. 주소 표시줄에 http://localhost/Tutorial/DisplayAds.asp를 입력하여 브라우저에서 예제를 봅니다.
<%@ Language=VBScript %>
<html>
<head>
<title>Display an Advertisement</title>
</head>
<body>
<font face="MS Gothic">
<h2>Display an Advertisement</h2>
<comment>Include the file you created to get an advertisement.</comment>
<!-- #include File = "AdRotatorLogic.inc" -->
<comment>Call the Function in the include file.</comment>
<%=GetAd()%>
</font>
</body>
</html>
브라우저에 다음과 같이 표시되어야 합니다.
Display an Advertisement
광고의 변경 내용을 보려면 브라우저에서 새로 고침 단추를 약 20번 클릭합니다. AdRotRedirect.asp가 광고주의 웹 사이트로 리디렉션하는 방법을 보려면 광고를 클릭합니다. 광고를 클릭했을 때 기록되는 내용을 보려면 AdRotLog.txt를 엽니다.
사용자가 웹 페이지를 요청하거나 방문한 횟수를 확인하는 데 유용합니다. 소통량이 큰 웹 사이트일수록 광고 수익도 큽니다. 일부 웹 사이트는 이 데이터를 사용하여 방문 횟수에 따라 광고주에게 고정 요금을 부과합니다. 또한 소통 정보를 사용하여 사용자가 해당 사이트를 탐색하는 방법과 광고를 게시할 위치도 알 수 있습니다. 사용자가 한 번도 방문하지 않는 페이지는 디자인을 변경해야 합니다.
PageCounter 구성 요소는 내부 개체를 사용하여 서버의 웹 페이지 방문 횟수를 기록합니다. 정전이나 시스템 오류로 인해 방문 횟수를 놓치지 않도록 PageCounter가 정기적으로 모든 정보를 텍스트 파일로 저장합니다. PageCounter 구성 요소는 다음 세 가지 메서드를 사용합니다.
다음 코드를 복사하여 텍스트 편집기에 붙여넣은 다음 파일을 x:\Inetpub\Wwwroot\Tutorial 디렉터리에 PageCounter.asp로 저장합니다. 주소 표시줄에 http://localhost/Tutorial/PageCounter.asp를 입력하여 브라우저에서 예제를 봅니다.
<%@ Language=VBScript %>
<html>
<head>
<title>Page Counter Example</title>
</head>
<body>
<font face="MS Gothic">
<H3>Page Counter Example</H3>
<p>
<FORM NAME="PageCounter" METHOD="GET" ACTION="PageCounter.asp">
<INPUT TYPE="CHECKBOX" NAME="reset" VALUE="True">Reset the Counter for this page?<BR>
<INPUT TYPE="SUBMIT" VALUE="Submit">
</FORM>
</p>
<%
'Instantiate the PageCounter object.
Set MyPageCounter = Server.CreateObject("MSWC.PageCounter")
'Increment the counter for this page.
MyPageCounter.PageHit
If Request.QueryString("reset") = "True" Then
'Reset the counter for this page.
MyPageCounter.Reset("/Tutorial/PageCounter.asp")
End If
%>
Hits to this page = <%=MyPageCounter.Hits %><BR>
</font>
</body>
</html>
브라우저에 다음과 같이 표시되어야 합니다.
Hits to this page = 1 Page Counter Example
방문 횟수가 증가하는 것을 보려면 브라우저의 새로 고침 단추를 클릭하거나 페이지의 Submit 단추를 클릭합니다. 방문 횟수를 초기화하려면 확인 상자를 클릭합니다.
이 단원에서는 Visual Basic을 사용하여 ASP 페이지에서 호출할 수 있는 간단한 COM 개체를 만듭니다. 이 예제에서는 ActiveX 마법사가 있는 Visual Basic이 필요하며 64비트 플랫폼용 Visual Basic 런타임이 개발될 때까지는 64비트 플랫폼에서 지원되지 않습니다. 64비트 플랫폼에서 실행되는 32비트 COM 개체를 만들지만 32비트 응용 프로그램에서 32비트 COM 개체를 호출해야 합니다. IIS는 64비트 플랫폼에서 실행되는 64비트 응용 프로그램이기 때문에 32비트 개체를 호출할 수 없습니다.
VBScript에 없는 기능을 필요로 하는 웹 응용 프로그램을 만들기 위해서는 응용 프로그램의 어떠한 ASP 페이지에서라도 필요에 따라 호출되는 사용자 정의 프로시저를 만들어야 합니다.
이 방법은 대개 사용자 지정 기능 캡슐화에 적합합니다. 그러나 많은 사용자를 대상으로 하는 서비스를 제공할 웹 응용 프로그램을 만드는 경우나 다른 사람에게 보이고 싶지 않은 소유 기능을 프로시저가 캡슐화하는 경우 COM 구성 요소의 폼에서 기능을 캡슐화하는 것이 좋습니다. 구성 요소는 컴파일된 코드이므로 스크립트 보다 우수한 보안과 성능을 제공합니다. 또한 구성 요소를 사용하여 Visual Basic, C++, Java 또는 다른 모든 COM 호환 언어의 기능을 사용할 수 있습니다.
Visual Basic의 ActiveX DLL 마법사는 COM 구성 요소를 만드는 가장 쉬운 방법입니다. 또한 Microsoft Visual C++에서 ATL(Active Template Library)를 사용하거나 모든 코드를 직접 써서 COM 구성 요소를 만들 수 있습니다. 이 예제에서는 Visual Basic을 사용합니다.
이 단원에서는 Visual Basic 기능을 구성 요소로 만들고 캡슐화하는 방법을 설명합니다. Visual Basic은 VBScript에는 사용할 수 없는 많은 재무 관련 함수를 가지고 있습니다. 이 예제에서는 고정 이율과 정기 고정 수입에 기초한 장래의 투자 값을 계산합니다.
Option Explicit
'Declare the global variables that will be set by the Property functions.
Dim gAnnualIntRate As Double
Dim gNumPayPeriods As Integer
Dim gPayment As Double
Dim gPresentSavings As Variant 'Optional
Dim gWhenDue As Variant 'Optional
Public Function CalcFutureValue() As Double
'The global variables you pass to the FV function are set
'when user sets the properties in the ASP page.
'You could pass variables into the CalcFutureValue() function
'if you wanted to avoid using properties.
'CalcFutureValue becomes a method in your component.
Dim IntRatePerPeriod As Double
Dim FullFutureValue As Double
If (gAnnualIntRate = Null) Or (gNumPayPeriods = Null) Or (gPayment = Null) Then
CalcFutureValue = 0
Else
IntRatePerPeriod = gAnnualIntRate / 100 / 12
FullFutureValue = FV(IntRatePerPeriod, gNumPayPeriods, gPayment, gPresentSavings, gWhenDue)
CalcFutureValue = Round(FullFutureValue, 2)
End If
End Function
Public Property Get AnnualIntRate() As Double
'Get functions return the value of the global variables
'as if they were properties.
'In your ASP page, you might say x = oASPTut.Rate.
AnnualIntRate = gAnnualIntRate
End Property
Public Property Let AnnualIntRate(ByVal vAnnualIntRate As Double)
'Let functions set the global variables when your ASP page
'makes a call such as oASPTut.Rate = 5.
gAnnualIntRate = vAnnualIntRate
End Property
Public Property Get NumPayPeriods() As Integer
NumPayPeriods = gNumPayPeriods
End Property
Public Property Let NumPayPeriods(ByVal vNumPayPeriods As Integer)
gNumPayPeriods = vNumPayPeriods
End Property
Public Property Get Payment() As Double
Payment = gPayment
End Property
Public Property Let Payment(ByVal vPayment As Double)
gPayment = -(vPayment)
End Property
Public Property Get PresentSavings() As Variant
PresentSavings = gPresentSavings
End Property
Public Property Let PresentSavings(ByVal vPresentSavings As Variant)
gPresentSavings = -(vPresentSavings)
End Property
Public Property Get WhenDue() As Variant
WhenDue = gWhenDue
End Property
Public Property Let WhenDue(ByVal vWhenDue As Variant)
gWhenDue = vWhenDue
End Property
이 예제 ASP 페이지에서는 폼을 사용하여 사용자 데이터에서 읽고 개체의 인스턴스를 만들고 앞으로의 저축 계획에 대한 값을 계산합니다.
다음 코드를 복사하여 텍스트 편집기에 붙여넣고 x:\Inetpub\Wwwroot\Tutorial 디렉터리에 파일을 CalculateFutureValue.asp로 저장합니다. 주소 표시줄에 http://localhost/Tutorial/CalculateFutureValue.asp 를 입력하여 브라우저에서 예제를 봅니다.
<%@ Language=VBScript %>
<%
Response.Expires = 0
Payment = Request.Form("Payment")
AnnualIntRate = Request.Form("AnnualIntRate")
NumPayPeriods = Request.Form("NumPayPeriods")
WhenDue = Request.Form("WhenDue")
PresentSavings = Request.Form("PresentSavings")
%>
<HTML>
<HEAD><TITLE>Future Value Calculation</TITLE></HEAD>
<BODY>
<FONT FACE="MS Gothic">
<H2 align=center>Calculate the Future Value of a Savings Plan</H2>
<FORM METHOD=POST ACTION="calculatefuturevalue.asp">
<TABLE cellpadding=4 align=center>
<TR>
<TD>How much do you plan to save each month?</TD>
<TD><INPUT TYPE=TEXT NAME=Payment VALUE=<%=Payment%>> (Required)</TD>
</TR><TR>
<TD>Enter the annual interest rate.</TD>
<TD><INPUT TYPE=TEXT NAME=AnnualIntRate VALUE=<%=AnnualIntRate%>> (Required)</TD>
</TR><TR>
<TD>For how many months will you save?</TD>
<TD><INPUT TYPE=TEXT NAME=NumPayPeriods VALUE=<%=NumPayPeriods%>> (Required)</TD>
</TR><TR>
<TD>When do you make payments in the month? </TD>
<TD><INPUT TYPE=RADIO NAME=WhenDue VALUE=1 <%If 1=WhenDue Then Response.Write"CHECKED"%>>Beginning
<INPUT TYPE=RADIO NAME=WhenDue VALUE=0 <%If 0=WhenDue Then Response.Write"CHECKED"%>>End </TD>
</TR><TR>
<TD>How much is in this savings account now?</TD>
<TD><INPUT TYPE=TEXT NAME=PresentSavings VALUE=<%=PresentSavings%>> </TD>
</TR>
</TABLE>
<P align=center><INPUT TYPE=SUBMIT VALUE=" Calculate Future Value ">
</FORM>
<%
If ("" = Payment) Or ("" = AnnualIntRate) Or ("" = NumPayPeriods) Then
Response.Write "<H3 align=center>No valid input entered yet.</H3>"
ElseIf (IsNumeric(Payment)) And (IsNumeric(AnnualIntRate)) And (IsNumeric(NumPayPeriods)) Then
Dim FutureValue
Set oASPTut = Server.CreateObject("ASPTut.Finance")
oASPTut.AnnualIntRate = CDbl(AnnualIntRate)
oASPTut.NumPayPeriods = CInt(NumPayPeriods)
oASPTut.Payment = CDbl(Payment)
If Not "" = PresentSavings Then oASPTut.PresentSavings = CDbl(PresentSavings)
oASPTut.WhenDue = WhenDue
FutureValue = oASPTut.CalcFutureValue
Response.Write "<H3 align=center>Future value = $" & FutureValue & "</H3>"
Else
Response.Write "<H3 align=center>Some of your values are not numbers.</H3>"
End If
%>
</FONT>
</BODY>
</HTML>
브라우저에 다음과 같이 표시되어야 합니다.
Calculate the Future Value of a Savings Plan
No valid input entered yet.
이 단원에서는 Microsoft® Visual J++®를 사용하여 단원 3의 Visual Basic 구성 요소와 다른 작업을 수행하는 COM 개체를 만듭니다. Visual J++ 6.0 이상이 필요합니다.
public class ASPTut
{
}
public double CalcFutureValue(
double dblAnnualIntRate,
double dblNumPayPeriods,
double dblPayment,
double dblPresentSavings,
boolean bWhenDue)
{
double dblRet, dblTemp, dblTemp2, dblTemp3, dblIntRate;
if (dblAnnualIntRate == 0.0)
{
dblRet = -dblPresentSavings - dblPayment * dblNumPayPeriods;
}
else
{
dblIntRate = dblAnnualIntRate / 100 / 12;
dblPayment = -dblPayment;
dblPresentSavings = -dblPresentSavings;
dblTemp = (bWhenDue ? 1.0 + dblIntRate : 1.0);
dblTemp3 = 1.0 + dblIntRate;
dblTemp2 = Math.pow(dblTemp3, dblNumPayPeriods);
dblRet = -dblPresentSavings * dblTemp2 - dblPayment * dblTemp * (dblTemp2 - 1.0) / dblIntRate;
}
return dblRet;
}이 예제 ASP 페이지에서는 폼을 사용하여 사용자 데이터에서 읽고 개체의 인스턴스를 만들고 앞으로의 저축에 대한 값을 계산합니다. 이 예제에서는 Jscript를 사용하지만 VBScript에서 Java 구성 요소를 호출할 수도 있습니다.
다음 코드를 복사하여 텍스트 편집기에 붙여넣고 x:\Inetpub\wwwroot\Tutorial 디렉터리에 파일을 CalculateFutureValueJava.asp로 저장합니다. 주소 표시줄에 http://localhost/Tutorial/CalculateFutureValueJava.asp를 입력하여 브라우저에서 예제를 봅니다.
<%@ Language=JScript %>
<%
Response.Expires = 0;
Payment = Request.Form("Payment");
AnnualIntRate = Request.Form("AnnualIntRate");
NumPayPeriods = Request.Form("NumPayPeriods");
WhenDue = Request.Form("WhenDue");
PresentSavings = Request.Form("PresentSavings");
%>
<HTML>
<HEAD><TITLE>Future Value Calculation - Java</TITLE></HEAD>
<BODY>
<FONT FACE="MS Gothic">
<H2 align=center>Calculate the Future Value of a Savings Plan</H2>
<FORM METHOD=POST ACTION="calculatefuturevaluejava.asp">
<TABLE cellpadding=4 align=center>
<TR>
<TD>How much do you plan to save each month?</TD>
<TD><INPUT TYPE=TEXT NAME=Payment VALUE=<%=Payment%>> (Required)</TD>
</TR><TR>
<TD>Enter the annual interest rate.</TD>
<TD><INPUT TYPE=TEXT NAME=AnnualIntRate VALUE=<%=AnnualIntRate%>> (Required)</TD>
</TR><TR>
<TD>For how many months will you save?</TD>
<TD><INPUT TYPE=TEXT NAME=NumPayPeriods VALUE=<%=NumPayPeriods%>> (Required)</TD>
</TR><TR>
<TD>When do you make payments in the month? </TD>
<TD><INPUT TYPE=RADIO NAME=WhenDue VALUE=1 <%if (1==WhenDue) Response.Write("CHECKED")%>>Beginning
<INPUT TYPE=RADIO NAME=WhenDue VALUE=0 <%if (0==WhenDue) Response.Write("CHECKED")%>>End </TD>
</TR><TR>
<TD>How much is in this savings account now?</TD>
<TD><INPUT TYPE=TEXT NAME=PresentSavings VALUE=<%=PresentSavings%>> </TD>
</TR>
</TABLE>
<P align=center><INPUT TYPE=SUBMIT VALUE=" Calculate Future Value ">
</FORM>
<%
if (("" == Payment) || ("" == AnnualIntRate) || ("" == NumPayPeriods)) {
Response.Write("<H3 align=center>No valid input entered yet.</H3>");
} else {
AnnualIntRate = parseFloat(AnnualIntRate)
NumPayPeriods = parseFloat(NumPayPeriods)
Payment = parseFloat(Payment)
if ("" != PresentSavings) PresentSavings = parseFloat(PresentSavings);
if ((isNaN(Payment)) || (isNaN(AnnualIntRate)) || (isNaN(NumPayPeriods))) {
Response.Write("<H3 align=center>Some of your values are not numbers.</H3>");
} else {
var FutureValue, Cents;
var oASPTut = Server.CreateObject("MS.ASPTut.Java");
FutureValue = oASPTut.CalcFutureValue(AnnualIntRate, NumPayPeriods, Payment, PresentSavings, WhenDue);
Response.Write("<H3 align=center>Future value = $" + parseInt(FutureValue) + "</H3>");
}
}
%>
</FONT>
</BODY>
</HTML>
브라우저에 다음 내용이 표시되어야 하며 이 모듈의 단원 3에서 설명한 Visual Basic 구성 요소를 사용하여 생성된 표시 내용과 같아야 합니다.
Calculate the Future Value of a Savings Plan
No valid input entered yet.