[
  {
    "path": "D1/Sequence Diagram/Sequence1.drawio",
    "content": "<mxfile host=\"app.diagrams.net\" agent=\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36\" version=\"29.6.0\">\n  <diagram name=\"Page-1\" id=\"y0SlUyap2nFQ304lxbyJ\">\n    <mxGraphModel dx=\"2197\" dy=\"920\" grid=\"1\" gridSize=\"10\" guides=\"1\" tooltips=\"1\" connect=\"1\" arrows=\"1\" fold=\"1\" page=\"1\" pageScale=\"1\" pageWidth=\"850\" pageHeight=\"1100\" background=\"none\" math=\"0\" shadow=\"0\">\n      <root>\n        <mxCell id=\"0\" />\n        <mxCell id=\"1\" parent=\"0\" />\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-1\" parent=\"1\" style=\"rounded=0;whiteSpace=wrap;html=1;fontFamily=Times New Roman;\" value=\":LabManager\" vertex=\"1\">\n          <mxGeometry height=\"60\" width=\"120\" x=\"1450\" y=\"100\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-2\" parent=\"1\" style=\"rounded=0;whiteSpace=wrap;html=1;fontFamily=Times New Roman;\" value=\":HeadLabCoordinator\" vertex=\"1\">\n          <mxGeometry height=\"60\" width=\"140\" x=\"1205\" y=\"100\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-3\" parent=\"1\" style=\"rounded=0;whiteSpace=wrap;html=1;fontFamily=Times New Roman;\" value=\":DeptApprovalServive\" vertex=\"1\">\n          <mxGeometry height=\"60\" width=\"140\" x=\"960\" y=\"100\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-4\" parent=\"1\" style=\"rounded=0;whiteSpace=wrap;html=1;fontFamily=Times New Roman;\" value=\":UserDatabase\" vertex=\"1\">\n          <mxGeometry height=\"60\" width=\"120\" x=\"740\" y=\"90\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-5\" parent=\"1\" style=\"rounded=0;whiteSpace=wrap;html=1;fontFamily=Times New Roman;\" value=\":AuthenticationService\" vertex=\"1\">\n          <mxGeometry height=\"60\" width=\"140\" x=\"490\" y=\"90\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-6\" parent=\"1\" style=\"rounded=0;whiteSpace=wrap;html=1;fontFamily=Times New Roman;\" value=\":RegistrationUI\" vertex=\"1\">\n          <mxGeometry height=\"60\" width=\"120\" x=\"180\" y=\"90\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-7\" parent=\"1\" style=\"rounded=0;whiteSpace=wrap;html=1;fontFamily=Times New Roman;\" value=\":User&lt;div&gt;(Student/Faculty/ Researcher/Guest)&lt;/div&gt;\" vertex=\"1\">\n          <mxGeometry height=\"60\" width=\"120\" x=\"20\" y=\"90\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-8\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"Sequence Diagram 1: Registration &amp;amp; Account Management&amp;nbsp;&lt;div&gt;[Req1, Req2, Req8] - Flows: User registration, LogIn, Auto-Generate Manager Account&amp;nbsp;&lt;/div&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"470\" x=\"240\" y=\"40\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-9\" edge=\"1\" parent=\"1\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-7\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"80\" y=\"2040\" as=\"sourcePoint\" />\n            <mxPoint x=\"400\" y=\"330\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-10\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-43\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-6\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"240\" y=\"581.2698800223214\" as=\"sourcePoint\" />\n            <mxPoint x=\"290.72\" y=\"29.999999999999943\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-11\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-38\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-5\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"560\" y=\"1460\" as=\"sourcePoint\" />\n            <mxPoint x=\"400\" y=\"340\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-12\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-46\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-4\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"800\" y=\"1510\" as=\"sourcePoint\" />\n            <mxPoint x=\"450\" y=\"300\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-13\" edge=\"1\" parent=\"1\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.557;entryY=1.028;entryDx=0;entryDy=0;entryPerimeter=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-3\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"1038\" y=\"2040\" as=\"sourcePoint\" />\n            <mxPoint x=\"700\" y=\"500\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-14\" edge=\"1\" parent=\"1\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-2\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1280\" y=\"2040\" />\n            </Array>\n            <mxPoint x=\"1280\" y=\"1920\" as=\"sourcePoint\" />\n            <mxPoint x=\"1110\" y=\"470\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-15\" edge=\"1\" parent=\"1\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.567;entryY=1.061;entryDx=0;entryDy=0;entryPerimeter=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-1\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1520\" y=\"2040\" />\n              <mxPoint x=\"1520\" y=\"1910\" />\n            </Array>\n            <mxPoint x=\"1520\" y=\"1910\" as=\"sourcePoint\" />\n            <mxPoint x=\"940\" y=\"450\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-16\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"&lt;u&gt;&lt;b&gt;&lt;font style=&quot;font-size: 16px;&quot;&gt;Section 1 - User Registration (Req1, Req8)&lt;/font&gt;&lt;/b&gt;&lt;/u&gt;\" vertex=\"1\">\n          <mxGeometry height=\"40\" width=\"300\" x=\"20\" y=\"170\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-18\" edge=\"1\" parent=\"1\" style=\"endArrow=classic;html=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"80\" y=\"240\" as=\"sourcePoint\" />\n            <mxPoint x=\"240\" y=\"240\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-19\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"1: fillRegistrationForm(email, pwd,&amp;nbsp;&lt;div&gt;userType, studentID&lt;/div&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"270\" x=\"15\" y=\"210\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-28\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-101\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"240\" y=\"1880\" as=\"sourcePoint\" />\n            <mxPoint x=\"240\" y=\"580\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-30\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-43\" style=\"html=1;align=left;spacingLeft=2;endArrow=block;rounded=0;edgeStyle=orthogonalEdgeStyle;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"&amp;nbsp;2: validateEmailFormat(email)&lt;div&gt;&lt;br&gt;&lt;/div&gt;\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"300\" y=\"260\" />\n              <mxPoint x=\"300\" y=\"290\" />\n            </Array>\n            <mxPoint x=\"270\" y=\"260\" as=\"sourcePoint\" />\n            <mxPoint x=\"245\" y=\"290\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-32\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"3:checkEmailUniqueness(email)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"140\" x=\"290\" y=\"290\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-39\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-103\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-38\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"560\" y=\"1890\" as=\"sourcePoint\" />\n            <mxPoint x=\"560\" y=\"150\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-38\" parent=\"1\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"480\" width=\"10\" x=\"555\" y=\"280\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-40\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-38\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"390\" y=\"320\" />\n            </Array>\n            <mxPoint x=\"245\" y=\"320\" as=\"sourcePoint\" />\n            <mxPoint x=\"550\" y=\"320\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-44\" edge=\"1\" parent=\"1\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-43\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"240\" y=\"581.2698800223214\" as=\"sourcePoint\" />\n            <mxPoint x=\"240\" y=\"150\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-43\" parent=\"1\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"630\" width=\"10\" x=\"235\" y=\"240\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-45\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontSize=9;fontFamily=Times New Roman;\" value=\"&lt;font&gt;2&lt;/font&gt;&lt;div&gt;&lt;font&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font&gt;3&lt;/font&gt;&lt;/div&gt;\" vertex=\"1\">\n          <mxGeometry height=\"25\" width=\"40\" x=\"220\" y=\"255\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-47\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-105\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-46\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"800\" y=\"1910\" as=\"sourcePoint\" />\n            <mxPoint x=\"800\" y=\"150\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-46\" parent=\"1\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"80\" width=\"10\" x=\"795\" y=\"320\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-48\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-38\" value=\"5r: emailExists: Boolean\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"790\" y=\"360\" as=\"sourcePoint\" />\n            <mxPoint x=\"600\" y=\"360\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-50\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-38\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"680\" y=\"320\" />\n            </Array>\n            <mxPoint x=\"630\" y=\"300\" as=\"sourcePoint\" />\n            <mxPoint x=\"800\" y=\"320\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-51\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"4:queryEmail(email)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"60\" x=\"650\" y=\"290\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-52\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"&lt;font style=&quot;font-size: 9px;&quot;&gt;4&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"15\" width=\"20\" x=\"550\" y=\"305\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-54\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fillStyle=auto;fillColor=default;gradientColor=none;shadow=0;swimlaneFillColor=default;fontFamily=Times New Roman;\" value=\"alt\" vertex=\"1\">\n          <mxGeometry height=\"130\" width=\"820\" x=\"30\" y=\"400\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-57\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"[email already exists]\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"120\" x=\"80\" y=\"420\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-59\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-54\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.998;entryY=0.606;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.62;exitDx=0;exitDy=0;exitPerimeter=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-54\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"400\" y=\"470\" as=\"sourcePoint\" />\n            <mxPoint x=\"450\" y=\"420\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-63\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"5a: error (&#39;Email already registered&#39;)\">\n          <mxGeometry relative=\"1\" x=\"0.0164\" y=\"-5\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <mxPoint x=\"555\" y=\"434.55\" as=\"sourcePoint\" />\n            <mxPoint x=\"250\" y=\"434.55\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-64\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"5b: emailAvailable\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"555\" y=\"510\" as=\"sourcePoint\" />\n            <mxPoint x=\"250\" y=\"510\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-65\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"email is unique\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"100\" x=\"130\" y=\"450\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-66\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fillStyle=auto;fillColor=default;gradientColor=none;shadow=0;swimlaneFillColor=default;fontFamily=Times New Roman;\" value=\"alt\" vertex=\"1\">\n          <mxGeometry height=\"130\" width=\"820\" x=\"40\" y=\"620\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-67\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"7a: error(&#39;Must include upper, lower, number, symbol&#39;)\">\n          <mxGeometry relative=\"1\" x=\"0.1111\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <mxPoint x=\"555\" y=\"659.09\" as=\"sourcePoint\" />\n            <mxPoint x=\"250\" y=\"659.09\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-68\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-66\" style=\"endArrow=none;dashed=1;html=1;rounded=0;exitX=0.002;exitY=0.485;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.999;entryY=0.499;entryDx=0;entryDy=0;entryPerimeter=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-66\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"270\" y=\"702\" as=\"sourcePoint\" />\n            <mxPoint x=\"860\" y=\"700\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-69\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"7b: passwordValid()\">\n          <mxGeometry relative=\"1\" x=\"0.1556\" y=\"-10\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <Array as=\"points\">\n              <mxPoint x=\"325\" y=\"720\" />\n            </Array>\n            <mxPoint x=\"555\" y=\"720\" as=\"sourcePoint\" />\n            <mxPoint x=\"255\" y=\"720\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-70\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"Strong password\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"100\" x=\"145\" y=\"660\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-71\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"[weak password]\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"120\" x=\"80\" y=\"630\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-72\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-74\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;exitX=0.75;exitY=1;exitDx=0;exitDy=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\" />\n            <mxPoint x=\"360\" y=\"550\" as=\"sourcePoint\" />\n            <mxPoint x=\"550\" y=\"560\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-73\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"6:validatePasswordStrength(password)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"140\" x=\"310\" y=\"530\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-74\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"&lt;font style=&quot;font-size: 8px;&quot;&gt;6&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"20\" x=\"230\" y=\"530\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-78\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"8: registerUser(email, hashedPwd, userType, studentID\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"310\" x=\"240\" y=\"770\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-79\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\" />\n            <mxPoint x=\"245\" y=\"800\" as=\"sourcePoint\" />\n            <mxPoint x=\"555\" y=\"800\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-83\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fillStyle=auto;fillColor=default;gradientColor=none;shadow=0;swimlaneFillColor=default;fontFamily=Times New Roman;\" value=\"opt\" vertex=\"1\">\n          <mxGeometry height=\"170\" width=\"1080\" x=\"40\" y=\"910\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-84\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"userType = Student | Faculty | Researcher\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"290\" x=\"80\" y=\"910\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-85\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\" />\n            <mxPoint x=\"560\" y=\"840\" as=\"sourcePoint\" />\n            <mxPoint x=\"800\" y=\"840\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-86\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"9: createUserRecord (userDTO)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"190\" x=\"580\" y=\"810\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-87\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"10r: userID: String\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"800\" y=\"880\" as=\"sourcePoint\" />\n            <mxPoint x=\"560\" y=\"880\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-91\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <mxPoint x=\"565\" y=\"970\" as=\"sourcePoint\" />\n            <mxPoint x=\"1040\" y=\"970\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-94\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=block;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"11: setAccountStatus(userID, &#39;PENDING&#39;)\">\n          <mxGeometry relative=\"1\" width=\"80\" as=\"geometry\">\n            <mxPoint x=\"1045\" y=\"1010\" as=\"sourcePoint\" />\n            <mxPoint x=\"805\" y=\"1010\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-95\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"10: sendApprovalRequest(userID, dept)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"220\" x=\"690\" y=\"940\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-96\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"12r: approvalPending()\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"1037.5\" y=\"1060\" as=\"sourcePoint\" />\n            <mxPoint x=\"562.5\" y=\"1060\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-97\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"14: display(&#39;Registration submitted: Awaiting Approval if applicable&#39;)\">\n          <mxGeometry relative=\"1\" x=\"-0.125\" y=\"-10\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <mxPoint x=\"240\" y=\"1200\" as=\"sourcePoint\" />\n            <mxPoint x=\"80\" y=\"1200\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-98\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"13: registrationSuccess(userID, status)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"560\" y=\"1160\" as=\"sourcePoint\" />\n            <mxPoint x=\"240\" y=\"1160\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-99\" parent=\"1\" style=\"text;whiteSpace=wrap;html=1;fontFamily=Times New Roman;\" value=\"&lt;div style=&quot;text-align: center;&quot;&gt;&lt;br&gt;&lt;/div&gt;\" vertex=\"1\">\n          <mxGeometry height=\"40\" width=\"290\" x=\"30\" y=\"1240\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-100\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"&lt;font style=&quot;font-size: 18px;&quot;&gt;&lt;u style=&quot;&quot;&gt;&lt;b style=&quot;&quot;&gt;Section 2 - User Login Flow (Req1)&lt;/b&gt;&lt;/u&gt;&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"280\" x=\"-20\" y=\"1210\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-102\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-139\" style=\"endArrow=none;dashed=1;html=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"240\" y=\"1880\" as=\"sourcePoint\" />\n            <mxPoint x=\"240\" y=\"1520\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-101\" parent=\"1\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"260\" width=\"20\" x=\"220\" y=\"1260\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-104\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-141\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-103\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"560\" y=\"1890\" as=\"sourcePoint\" />\n            <mxPoint x=\"560\" y=\"760\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-103\" parent=\"1\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"160\" width=\"10\" x=\"555\" y=\"1270\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-106\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-152\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-105\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"800\" y=\"1910\" as=\"sourcePoint\" />\n            <mxPoint x=\"800\" y=\"410\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-105\" parent=\"1\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"100\" width=\"10\" x=\"795\" y=\"1290\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-107\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fillStyle=auto;fillColor=default;gradientColor=none;shadow=0;swimlaneFillColor=default;fontFamily=Times New Roman;\" value=\"alt\" vertex=\"1\">\n          <mxGeometry height=\"140\" width=\"820\" x=\"50\" y=\"1350\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-109\" edge=\"1\" parent=\"1\" style=\"endArrow=none;dashed=1;html=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"50\" y=\"1460\" as=\"sourcePoint\" />\n            <mxPoint x=\"870\" y=\"1460\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-111\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"[credentials invalid]\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"120\" x=\"110\" y=\"1350\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-113\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"credentials valid ACTIVE\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"140\" x=\"50\" y=\"1430\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-114\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;exitX=1;exitY=0;exitDx=0;exitDy=5;exitPerimeter=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"240\" y=\"1280\" />\n            </Array>\n            <mxPoint x=\"245\" y=\"1255\" as=\"sourcePoint\" />\n            <mxPoint x=\"560\" y=\"1280\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-115\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"18a: authFailed(&#39;Invalid email or password&#39;)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"555.0000000000002\" y=\"1380.0000000000002\" as=\"sourcePoint\" />\n            <mxPoint x=\"245\" y=\"1380\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-116\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"18b: authFailed(&#39;Account awaiting departmental approval&#39;)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"547.5\" y=\"1445.45\" as=\"sourcePoint\" />\n            <mxPoint x=\"242.5\" y=\"1444.54\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-118\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"18c:authSuccess(sessionToken, userType, hourlyRate)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"555\" y=\"1480\" as=\"sourcePoint\" />\n            <mxPoint x=\"250\" y=\"1480\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-120\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"18r: userRecord(hasedPwd, status, userType)\">\n          <mxGeometry relative=\"1\" x=\"0.0222\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <mxPoint x=\"795\" y=\"1330\" as=\"sourcePoint\" />\n            <mxPoint x=\"570\" y=\"1330\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-121\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"17:&amp;nbsp; fetchUserRecord(email)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"180\" x=\"585\" y=\"1270\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-122\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"16: authenticateUser(email, password)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"230\" x=\"270\" y=\"1250\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-125\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-101\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;exitX=1;exitY=0;exitDx=0;exitDy=5;exitPerimeter=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\" />\n            <mxPoint x=\"240\" y=\"1265\" as=\"sourcePoint\" />\n            <mxPoint x=\"240\" y=\"1265\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-127\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <mxPoint x=\"565\" y=\"1300\" as=\"sourcePoint\" />\n            <mxPoint x=\"565.037037037037\" y=\"1300\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-128\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <mxPoint x=\"565\" y=\"1300\" as=\"sourcePoint\" />\n            <mxPoint x=\"790\" y=\"1300\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-130\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"&lt;font style=&quot;font-size: 8px;&quot;&gt;19: display(Dashboard for userType)&lt;/font&gt;\">\n          <mxGeometry relative=\"1\" x=\"0.125\" y=\"-10\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <mxPoint x=\"240\" y=\"1520\" as=\"sourcePoint\" />\n            <mxPoint x=\"80\" y=\"1520\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-133\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <mxPoint x=\"80\" y=\"1260.91\" as=\"sourcePoint\" />\n            <mxPoint x=\"225\" y=\"1260\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-135\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"&lt;font style=&quot;font-size: 8px;&quot;&gt;15: submitLogin(email, password)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"230\" x=\"60\" y=\"1240\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-137\" edge=\"1\" parent=\"1\" style=\"endArrow=none;dashed=1;html=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"50\" y=\"1410\" as=\"sourcePoint\" />\n            <mxPoint x=\"870\" y=\"1410\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-138\" connectable=\"0\" parent=\"jcZRHxVDqwLQwtNWG9ev-137\" style=\"edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontFamily=Times New Roman;\" value=\"account PENDING\" vertex=\"1\">\n          <mxGeometry relative=\"1\" x=\"-0.8421\" y=\"8\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-140\" edge=\"1\" parent=\"1\" style=\"endArrow=none;dashed=1;html=1;rounded=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-139\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"240\" y=\"2040\" as=\"sourcePoint\" />\n            <mxPoint x=\"240\" y=\"1520\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-139\" parent=\"1\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"260\" width=\"32.5\" x=\"227.5\" y=\"1630\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-142\" edge=\"1\" parent=\"1\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-141\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"560\" y=\"2040\" as=\"sourcePoint\" />\n            <mxPoint x=\"560\" y=\"1430\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-141\" parent=\"1\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"180\" width=\"25\" x=\"547.5\" y=\"1660\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-143\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-139\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;exitX=0.9;exitY=0.16;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.1;entryY=0.111;entryDx=0;entryDy=0;entryPerimeter=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-141\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"260\" y=\"1680\" />\n            </Array>\n            <mxPoint x=\"310\" y=\"1810\" as=\"sourcePoint\" />\n            <mxPoint x=\"470\" y=\"1810\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-145\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-139\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-141\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"380\" y=\"1760\" />\n            </Array>\n            <mxPoint x=\"310\" y=\"1810\" as=\"sourcePoint\" />\n            <mxPoint x=\"470\" y=\"1810\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-146\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-141\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"22r: role Verified: TRUE\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"332.5\" y=\"1720\" as=\"sourcePoint\" />\n            <mxPoint x=\"252.5\" y=\"1720\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-147\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"25:accountCreated(managerID, tempPasswword)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\" />\n            <mxPoint x=\"560\" y=\"1900\" as=\"sourcePoint\" />\n            <mxPoint x=\"240\" y=\"1900\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-148\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"21: verifyHeadCoordinatorRole(hlcSessionToken)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"310\" x=\"245\" y=\"1650\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-150\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"22: createManagerAccount(managerDTO)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"230\" x=\"300\" y=\"1730\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-153\" edge=\"1\" parent=\"1\" style=\"endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontFamily=Times New Roman;\" target=\"jcZRHxVDqwLQwtNWG9ev-152\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"800\" y=\"2040\" as=\"sourcePoint\" />\n            <mxPoint x=\"800\" y=\"1390\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-152\" parent=\"1\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"80\" width=\"20\" x=\"790\" y=\"1720\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-154\" edge=\"1\" parent=\"1\" source=\"jcZRHxVDqwLQwtNWG9ev-141\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"570\" y=\"1800\" />\n            </Array>\n            <mxPoint x=\"580\" y=\"1800\" as=\"sourcePoint\" />\n            <mxPoint x=\"800\" y=\"1800\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-155\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"24r: managerID: String\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"630\" y=\"1850\" />\n            </Array>\n            <mxPoint x=\"800\" y=\"1850\" as=\"sourcePoint\" />\n            <mxPoint x=\"560\" y=\"1850\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-156\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"&lt;font style=&quot;font-size: 10px;&quot;&gt;23: insertManagerRecord(managerDTO)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"270\" x=\"555\" y=\"1770\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-161\" parent=\"1\" style=\"rounded=0;whiteSpace=wrap;html=1;fontFamily=Times New Roman;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"100\" width=\"240\" x=\"920\" y=\"1760\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-162\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fontFamily=Times New Roman;\" value=\"opt\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"60\" x=\"1160\" y=\"1760\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-163\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"role = HeadLabCoordinator\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"155\" x=\"1230\" y=\"1760\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-164\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;\" value=\"26: display(&#39;Manager account created. Credentials sent.&#39;)\">\n          <mxGeometry relative=\"1\" x=\"-0.0005\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <Array as=\"points\">\n              <mxPoint x=\"240\" y=\"1960\" />\n            </Array>\n            <mxPoint x=\"317.5\" y=\"1960\" as=\"sourcePoint\" />\n            <mxPoint x=\"1280\" y=\"1960\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-165\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <mxPoint x=\"800\" y=\"2000\" as=\"sourcePoint\" />\n            <mxPoint x=\"1520\" y=\"2000\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-166\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"27: sendCredentials(email, tempPassword)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"300\" x=\"910\" y=\"1970\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-167\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1280\" y=\"1630\" />\n            </Array>\n            <mxPoint x=\"1280\" y=\"1650\" as=\"sourcePoint\" />\n            <mxPoint x=\"260\" y=\"1640\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-169\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;\" value=\"20: requestGenerateManagerAccount(managerName, dept)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"370\" x=\"740\" y=\"1610\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"jcZRHxVDqwLQwtNWG9ev-170\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;\" value=\"&lt;b&gt;&lt;font style=&quot;font-size: 16px;&quot; face=&quot;Times New Roman&quot;&gt;&lt;u&gt;Section 3 - Auto-Generate Manager Account (Req2)&lt;/u&gt;&lt;/font&gt;&lt;/b&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"360\" x=\"-20\" y=\"1570\" as=\"geometry\" />\n        </mxCell>\n      </root>\n    </mxGraphModel>\n  </diagram>\n</mxfile>\n"
  },
  {
    "path": "D1/Sequence Diagram/Sequence2.drawio",
    "content": "<mxfile host=\"app.diagrams.net\" agent=\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36\" version=\"29.6.0\">\n  <diagram name=\"Page-1\" id=\"2YBvvXClWsGukQMizWep\">\n    <mxGraphModel dx=\"2686\" dy=\"2355\" grid=\"1\" gridSize=\"10\" guides=\"1\" tooltips=\"1\" connect=\"1\" arrows=\"1\" fold=\"1\" page=\"1\" pageScale=\"1\" pageWidth=\"850\" pageHeight=\"1100\" math=\"0\" shadow=\"0\">\n      <root>\n        <mxCell id=\"0\" />\n        <mxCell id=\"1\" parent=\"0\" />\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-3\" parent=\"1\" style=\"shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;dropTarget=0;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\":User (Student/Faculty/ Researcher/Guest\" vertex=\"1\">\n          <mxGeometry height=\"2940\" width=\"180\" x=\"30\" y=\"80\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-4\" parent=\"1\" style=\"shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;dropTarget=0;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\":BookingUI\" vertex=\"1\">\n          <mxGeometry height=\"2930\" width=\"207.5\" x=\"310\" y=\"80\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-10\" parent=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"360\" width=\"30\" x=\"75\" y=\"120\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-2\" parent=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"320\" width=\"15\" x=\"82.5\" y=\"820\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-33\" parent=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"240\" width=\"25\" x=\"77.5\" y=\"1690\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-49\" parent=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"380\" width=\"30\" x=\"85\" y=\"2170\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-5\" parent=\"1\" style=\"shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;dropTarget=0;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\":BookingSystem\" vertex=\"1\">\n          <mxGeometry height=\"2930\" width=\"180\" x=\"590\" y=\"80\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-11\" parent=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"290\" width=\"30\" x=\"75\" y=\"160\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-3\" parent=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"280\" width=\"15\" x=\"80\" y=\"830\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-23\" parent=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"230\" width=\"20\" x=\"77.5\" y=\"1360\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-34\" parent=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"240\" width=\"25\" x=\"80\" y=\"1710\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-50\" parent=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"310\" width=\"30\" x=\"80\" y=\"2200\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-6\" parent=\"1\" style=\"shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;dropTarget=0;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\":EquipmentDatabase\" vertex=\"1\">\n          <mxGeometry height=\"2930\" width=\"180\" x=\"870\" y=\"80\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-12\" parent=\"LfNKJZrtx-e5gq2OnKBV-6\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"160\" width=\"30\" x=\"75\" y=\"190\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-51\" parent=\"LfNKJZrtx-e5gq2OnKBV-6\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"120\" width=\"30\" x=\"75\" y=\"2290\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-7\" parent=\"1\" style=\"shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;dropTarget=0;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\":SensorSystem&lt;div&gt;&amp;lt;&amp;lt;external&amp;gt;&amp;gt;&lt;/div&gt;\" vertex=\"1\">\n          <mxGeometry height=\"2920\" width=\"180\" x=\"1430\" y=\"80\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-24\" parent=\"LfNKJZrtx-e5gq2OnKBV-7\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"80\" width=\"20\" x=\"80\" y=\"1380\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-8\" parent=\"1\" style=\"shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;dropTarget=0;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\":PaymentSystem&lt;div&gt;&amp;lt;&amp;lt;external&amp;gt;&amp;gt;&lt;/div&gt;\" vertex=\"1\">\n          <mxGeometry height=\"2930\" width=\"180\" x=\"1150\" y=\"80\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-4\" parent=\"LfNKJZrtx-e5gq2OnKBV-8\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"150\" width=\"15\" x=\"82.5\" y=\"850\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-9\" parent=\"1\" style=\"shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;dropTarget=0;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\":BookingDatabase\" vertex=\"1\">\n          <mxGeometry height=\"2920\" width=\"180\" x=\"1710\" y=\"80\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-5\" parent=\"LfNKJZrtx-e5gq2OnKBV-9\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"80\" width=\"10\" x=\"80\" y=\"940\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-26\" parent=\"LfNKJZrtx-e5gq2OnKBV-9\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"80\" width=\"10\" x=\"85\" y=\"1490\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-36\" parent=\"LfNKJZrtx-e5gq2OnKBV-9\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"110\" width=\"20\" x=\"80\" y=\"1770\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-14\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-3\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;entryPerimeter=0;fontFamily=Times New Roman;\" target=\"LfNKJZrtx-e5gq2OnKBV-10\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"150\" y=\"210\" />\n            </Array>\n            <mxPoint x=\"120\" y=\"200\" as=\"sourcePoint\" />\n            <mxPoint x=\"280\" y=\"200\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-15\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;entryPerimeter=0;fontFamily=Times New Roman;\" target=\"LfNKJZrtx-e5gq2OnKBV-11\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"460\" y=\"245\" />\n            </Array>\n            <mxPoint x=\"470\" y=\"280\" as=\"sourcePoint\" />\n            <mxPoint x=\"520\" y=\"280\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-17\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;entryPerimeter=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"750\" y=\"270\" />\n            </Array>\n            <mxPoint x=\"690\" y=\"270\" as=\"sourcePoint\" />\n            <mxPoint x=\"955\" y=\"270\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-18\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"LfNKJZrtx-e5gq2OnKBV-6\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"740\" y=\"540\" />\n            </Array>\n            <mxPoint x=\"680\" y=\"540\" as=\"sourcePoint\" />\n            <mxPoint x=\"945\" y=\"540\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-19\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;entryPerimeter=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"470\" y=\"520\" />\n            </Array>\n            <mxPoint x=\"410\" y=\"520\" as=\"sourcePoint\" />\n            <mxPoint x=\"675\" y=\"520\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-20\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;entryPerimeter=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"180\" y=\"480\" />\n            </Array>\n            <mxPoint x=\"120\" y=\"480\" as=\"sourcePoint\" />\n            <mxPoint x=\"385\" y=\"480\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-21\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"4r: display(EquipmentCatalogue)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"200\" y=\"440\" as=\"sourcePoint\" />\n            <mxPoint x=\"120\" y=\"440\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-22\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"4r: equipmentList\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"500\" y=\"400\" as=\"sourcePoint\" />\n            <mxPoint x=\"420\" y=\"400\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-23\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-6\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" target=\"LfNKJZrtx-e5gq2OnKBV-11\" value=\"&lt;font&gt;4r: equipmentList[] (equipID, desc, location, status)&lt;/font&gt;\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"780\" y=\"320\" />\n            </Array>\n            <mxPoint x=\"770\" y=\"360\" as=\"sourcePoint\" />\n            <mxPoint x=\"690\" y=\"360\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-24\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-6\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"7r: status = AVAILABLE&amp;nbsp;\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"760\" y=\"600\" as=\"sourcePoint\" />\n            <mxPoint x=\"680\" y=\"600\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-26\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fillStyle=auto;fillColor=default;gradientColor=none;shadow=0;swimlaneFillColor=default;fontFamily=Times New Roman;fontSize=12;\" value=\"alt\" vertex=\"1\">\n          <mxGeometry height=\"130\" width=\"1040\" x=\"70\" y=\"660\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-27\" edge=\"1\" parent=\"1\" style=\"endArrow=none;dashed=1;html=1;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"69.99666666666674\" y=\"724.33\" as=\"sourcePoint\" />\n            <mxPoint x=\"1110\" y=\"724\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-28\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"7a:error(&#39;Equipment unavailable for selected time&#39;)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"689.5\" y=\"690\" as=\"sourcePoint\" />\n            <mxPoint x=\"410\" y=\"690\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-29\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"7b: availabilityConfirmed(equipID, hourlyRate)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"699.5\" y=\"760\" as=\"sourcePoint\" />\n            <mxPoint x=\"420\" y=\"760\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-32\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-3\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"310\" y=\"840\" />\n            </Array>\n            <mxPoint x=\"250\" y=\"840\" as=\"sourcePoint\" />\n            <mxPoint x=\"400\" y=\"840\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-33\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;b&gt;&lt;u&gt;&lt;font style=&quot;font-size: 14px;&quot;&gt;Section 1: Broswse &amp;amp; Reserve Equipment (Req3, Req4, Req8)&lt;/font&gt;&lt;/u&gt;&lt;/b&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"380\" x=\"30\" y=\"140\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-34\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;1: BrowseEquipment(labLocation, EquipmentType)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"300\" x=\"90\" y=\"170\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-35\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;4:selectEquipment(equipID) + provideStudentID(SID)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"430\" x=\"40\" y=\"450\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-36\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;2: searchAvailableEquipment&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"200\" x=\"440\" y=\"210\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-37\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;5:checkEquipmentAvailability(equipID, startTime, endTime)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"390\" x=\"345\" y=\"490\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-38\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;3: queryAvailablleEquipment(filters)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"220\" x=\"710\" y=\"240\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-39\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;6: getEquipmentStatus(equipID)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"190\" x=\"725\" y=\"510\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-40\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"[equipment not available]\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"210\" x=\"100\" y=\"660\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-41\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"equipment AVAILABLE\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"130\" x=\"200\" y=\"700\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-43\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;8: confirmReservation(equipID, startTime, endTime)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"350\" x=\"90\" y=\"810\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-1\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;b&gt;&lt;u&gt;&lt;font style=&quot;font-size: 14px;&quot;&gt;Section 2 - Pay Deposit Flow (Req4, Req10)&lt;/font&gt;&lt;/u&gt;&lt;/b&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"270\" y=\"860\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-6\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-3\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"OIFvRv84QuahlJDP0eki-2\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"360\" y=\"940\" />\n              <mxPoint x=\"280\" y=\"950\" />\n            </Array>\n            <mxPoint x=\"120\" y=\"1000\" as=\"sourcePoint\" />\n            <mxPoint x=\"280\" y=\"1000\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-7\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;10: selectPayment(CREDIT| DEBIT| YUCARD)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"280\" x=\"115\" y=\"910\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-8\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"LfNKJZrtx-e5gq2OnKBV-5\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"660\" y=\"910\" />\n            </Array>\n            <mxPoint x=\"395.00034482758605\" y=\"900\" as=\"sourcePoint\" />\n            <mxPoint x=\"530\" y=\"890\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-60\" connectable=\"0\" parent=\"OIFvRv84QuahlJDP0eki-8\" style=\"edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontFamily=Times New Roman;fontSize=12;\" value=\"9: calculateDeposit(userType, hourlyRate)\" vertex=\"1\">\n          <mxGeometry relative=\"1\" x=\"-0.7329\" y=\"9\" as=\"geometry\">\n            <mxPoint x=\"107\" y=\"-1\" as=\"offset\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-9\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;10r: depositAmount(Student=$10, Faculty=$15, Researcher=$20, Guest = $30&lt;/font&gt;\">\n          <mxGeometry relative=\"1\" y=\"-10\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <Array as=\"points\">\n              <mxPoint x=\"461.25\" y=\"940\" />\n            </Array>\n            <mxPoint x=\"671.25\" y=\"940\" as=\"sourcePoint\" />\n            <mxPoint x=\"408.75\" y=\"940\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-10\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"OIFvRv84QuahlJDP0eki-3\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"400\" y=\"960\" />\n            </Array>\n            <mxPoint x=\"400\" y=\"960\" as=\"sourcePoint\" />\n            <mxPoint x=\"560\" y=\"970\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-11\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"OIFvRv84QuahlJDP0eki-4\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1240\" y=\"980\" />\n            </Array>\n            <mxPoint x=\"680\" y=\"980\" as=\"sourcePoint\" />\n            <mxPoint x=\"840\" y=\"980\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-12\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fillStyle=auto;fillColor=default;gradientColor=none;shadow=0;swimlaneFillColor=default;fontFamily=Times New Roman;fontSize=12;\" value=\"alt\" vertex=\"1\">\n          <mxGeometry height=\"130\" width=\"1040\" x=\"320\" y=\"1010\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-13\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"13a:paymentFailed(reason)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"1229.5000000000002\" y=\"1040\" as=\"sourcePoint\" />\n            <mxPoint x=\"680\" y=\"1040\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-14\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"13b: paymentConfirmed(transactionID, amount)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"1234.7500000000002\" y=\"1119.66\" as=\"sourcePoint\" />\n            <mxPoint x=\"685.25\" y=\"1119.66\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-15\" edge=\"1\" parent=\"1\" source=\"OIFvRv84QuahlJDP0eki-12\" style=\"endArrow=none;dashed=1;html=1;rounded=0;exitX=0;exitY=0.529;exitDx=0;exitDy=0;exitPerimeter=0;fontFamily=Times New Roman;fontSize=12;\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"339.81034482758605\" y=\"1079.66\" as=\"sourcePoint\" />\n            <mxPoint x=\"1360\" y=\"1079.66\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-16\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"13a2:error(&#39;Payment declined. Try again!&#39;)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"466.5\" y=\"1060\" />\n            </Array>\n            <mxPoint x=\"676\" y=\"1060\" as=\"sourcePoint\" />\n            <mxPoint x=\"434\" y=\"1060\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-18\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"LfNKJZrtx-e5gq2OnKBV-9\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1750\" y=\"1210\" />\n            </Array>\n            <mxPoint x=\"680\" y=\"1170\" as=\"sourcePoint\" />\n            <mxPoint x=\"840\" y=\"1170\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-19\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-9\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" target=\"LfNKJZrtx-e5gq2OnKBV-5\" value=\"15r: bookingID: String\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1020\" y=\"1230\" />\n            </Array>\n            <mxPoint x=\"1100\" y=\"830\" as=\"sourcePoint\" />\n            <mxPoint x=\"1020\" y=\"830\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-20\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" target=\"LfNKJZrtx-e5gq2OnKBV-4\" value=\"15r: bookingConfirmed(bookingID, depositAmt, schedule)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"510\" y=\"1270\" />\n            </Array>\n            <mxPoint x=\"790\" y=\"830\" as=\"sourcePoint\" />\n            <mxPoint x=\"710\" y=\"830\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-21\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" target=\"LfNKJZrtx-e5gq2OnKBV-3\" value=\"15r: display(&#39;Booking confirmed. BookingID returned&#39;)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"260\" y=\"1300\" />\n            </Array>\n            <mxPoint x=\"790\" y=\"830\" as=\"sourcePoint\" />\n            <mxPoint x=\"710\" y=\"830\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-22\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;b&gt;&lt;u&gt;&lt;font style=&quot;font-size: 14px;&quot;&gt;Section 3- Deposit Forfeit on No-Show (Req4)&lt;/font&gt;&lt;/u&gt;&lt;/b&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"290\" x=\"10\" y=\"1340\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-25\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fillStyle=auto;fillColor=default;gradientColor=none;shadow=0;swimlaneFillColor=default;fontFamily=Times New Roman;fontSize=12;\" value=\"opt\" vertex=\"1\">\n          <mxGeometry height=\"150\" width=\"1370\" x=\"570\" y=\"1490\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-27\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-7\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=5;entryPerimeter=0;fontFamily=Times New Roman;\" target=\"OIFvRv84QuahlJDP0eki-23\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1360\" y=\"1445\" />\n            </Array>\n            <mxPoint x=\"1130\" y=\"1450\" as=\"sourcePoint\" />\n            <mxPoint x=\"980\" y=\"1450\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-28\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1695\" y=\"1540\" />\n            </Array>\n            <mxPoint x=\"705\" y=\"1530\" as=\"sourcePoint\" />\n            <mxPoint x=\"1805\" y=\"1530\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-29\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1695\" y=\"1590\" />\n            </Array>\n            <mxPoint x=\"705\" y=\"1580\" as=\"sourcePoint\" />\n            <mxPoint x=\"1805\" y=\"1580\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-30\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"18r: updated\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1035.5\" y=\"1620\" />\n            </Array>\n            <mxPoint x=\"1815.5\" y=\"1620\" as=\"sourcePoint\" />\n            <mxPoint x=\"694.5\" y=\"1620\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-31\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;notify(userID, &#39;Deposit forfeited:no-show after 20 min&#39;)&lt;/font&gt;\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"680.27\" y=\"1670\" as=\"sourcePoint\" />\n            <mxPoint x=\"399.73153846153855\" y=\"1670\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-32\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;b&gt;&lt;u&gt;&lt;font style=&quot;font-size: 14px;&quot;&gt;Section 4 - Modify / Cancel Booking (Req8)&lt;/font&gt;&lt;/u&gt;&lt;/b&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"290\" x=\"-25\" y=\"1710\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-35\" edge=\"1\" parent=\"1\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;curved=0;fontFamily=Times New Roman;fontSize=12;\" value=\"\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"618.75\" y=\"1800\" />\n              <mxPoint x=\"618.75\" y=\"1800\" />\n            </Array>\n            <mxPoint x=\"411.2500000000002\" y=\"1800\" as=\"sourcePoint\" />\n            <mxPoint x=\"668.75\" y=\"1800\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-37\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" target=\"OIFvRv84QuahlJDP0eki-33\" value=\"21r:bookingStartTime &amp;gt; now -&amp;gt; modifiable\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"520\" y=\"1870\" />\n            </Array>\n            <mxPoint x=\"790\" y=\"1730\" as=\"sourcePoint\" />\n            <mxPoint x=\"710\" y=\"1730\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-40\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-3\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"130\" y=\"1800\" />\n            </Array>\n            <mxPoint x=\"235\" y=\"1780\" as=\"sourcePoint\" />\n            <mxPoint x=\"395\" y=\"1780\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-41\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fillStyle=auto;fillColor=default;gradientColor=none;shadow=0;swimlaneFillColor=default;fontFamily=Times New Roman;fontSize=12;\" value=\"alt\" vertex=\"1\">\n          <mxGeometry height=\"190\" width=\"1940\" x=\"30\" y=\"1910\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-42\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;startArrow=none;startFill=0;endSize=6;startSize=10;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1700.25\" y=\"1960\" />\n            </Array>\n            <mxPoint x=\"690.25\" y=\"1960\" as=\"sourcePoint\" />\n            <mxPoint x=\"1789.75\" y=\"1960\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-43\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;startArrow=none;startFill=0;endSize=6;startSize=10;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1700.25\" y=\"2040\" />\n            </Array>\n            <mxPoint x=\"690.25\" y=\"2040\" as=\"sourcePoint\" />\n            <mxPoint x=\"1789.75\" y=\"2040\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-44\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;startArrow=none;startFill=0;endSize=6;startSize=10;rounded=0;dashed=1;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1565.25\" y=\"2000\" />\n            </Array>\n            <mxPoint x=\"1784.75\" y=\"2000\" as=\"sourcePoint\" />\n            <mxPoint x=\"695.25\" y=\"2000\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-45\" edge=\"1\" parent=\"1\" style=\"endArrow=none;dashed=1;html=1;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"300\" y=\"2040\" />\n            </Array>\n            <mxPoint x=\"690\" y=\"2040\" as=\"sourcePoint\" />\n            <mxPoint x=\"30\" y=\"2040\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-47\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"21a2:modifyConfirmed(bookingID, newSchedule)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"527\" y=\"2020\" />\n            </Array>\n            <mxPoint x=\"687\" y=\"2020\" as=\"sourcePoint\" />\n            <mxPoint x=\"420\" y=\"2020\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-48\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;startArrow=none;startFill=0;endSize=6;startSize=10;rounded=0;dashed=1;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1560\" y=\"2080\" />\n            </Array>\n            <mxPoint x=\"1779.5\" y=\"2080\" as=\"sourcePoint\" />\n            <mxPoint x=\"690\" y=\"2080\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-52\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"440\" y=\"2270\" />\n            </Array>\n            <mxPoint x=\"520\" y=\"2280\" as=\"sourcePoint\" />\n            <mxPoint x=\"680\" y=\"2280\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-53\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-3\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"130\" y=\"2260\" />\n            </Array>\n            <mxPoint x=\"240\" y=\"2250\" as=\"sourcePoint\" />\n            <mxPoint x=\"400\" y=\"2250\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-55\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"LfNKJZrtx-e5gq2OnKBV-6\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"900\" y=\"2300\" />\n            </Array>\n            <mxPoint x=\"700\" y=\"2380\" as=\"sourcePoint\" />\n            <mxPoint x=\"860\" y=\"2380\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-56\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"26r: noConflict: Boolean\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"955\" y=\"2410\" as=\"sourcePoint\" />\n            <mxPoint x=\"695.5\" y=\"2410\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-59\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;b&gt;&lt;u&gt;&lt;font style=&quot;font-size: 14px;&quot;&gt;Section 5 - Extend Reservation (Req9)&lt;/font&gt;&lt;/u&gt;&lt;/b&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"250\" x=\"-20\" y=\"2170\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-64\" parent=\"1\" style=\"text;whiteSpace=wrap;fontSize=12;fontFamily=Times New Roman;\" value=\"11: initiatePayment(depositAmt, paymentMethod, userID)\" vertex=\"1\">\n          <mxGeometry height=\"20\" width=\"220\" x=\"440\" y=\"940\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-66\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;12: processPayment(depositAmt, paymentDetails)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"270\" x=\"685\" y=\"950\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-67\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;[payment DECLINED]&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"120\" x=\"370\" y=\"1010\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-69\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"payment SUCCESS\" vertex=\"1\">\n          <mxGeometry height=\"20\" width=\"110\" x=\"420\" y=\"1060\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-70\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"14: createBookingRecord(userID, equipID, startTime, depositPaid)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"380\" x=\"1065\" y=\"1140\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-71\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"15: reportUsageStatus(equipID, bookingID, arrivalDetected=FALSE)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"440\" x=\"1010\" y=\"1410\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-73\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"arrivalDetected=FALSE AND elapsed &amp;gt; 20 min\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"260\" x=\"710\" y=\"1500\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-74\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"16:updateDeposit(bookingID, status=&#39;FORFEITED&#39;)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"320\" x=\"1170\" y=\"1500\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-77\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"17: markBookingNoShow(bookingID)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"250\" x=\"1205\" y=\"1550\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-78\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"19: modifyOrCancelBooking(bookingID, action)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"265\" x=\"115\" y=\"1750\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-80\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"20: validateBookingModifiable(bookingID)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"235\" x=\"425\" y=\"1770\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-81\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"[action = MODIFY]\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"110\" x=\"90\" y=\"1910\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-82\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"action = CANCEL\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"110\" x=\"170\" y=\"2010\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-83\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"21a: updateBooking(bookingID, newStartTime, newEndTime)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"460\" x=\"960\" y=\"1930\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-84\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"21a_r: updated\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"355\" x=\"1065\" y=\"1970\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-85\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"21b: cancelBooking(bookingID)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"370\" x=\"1060\" y=\"2010\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-86\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"21b_r: cancelled + refundDeposit\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"200\" x=\"1150\" y=\"2050\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-87\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" target=\"LfNKJZrtx-e5gq2OnKBV-3\" value=\"22: display(&#39;Booking Updated Successfully&#39;)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"410\" y=\"2150\" as=\"sourcePoint\" />\n            <mxPoint x=\"330\" y=\"2150\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-88\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fillStyle=auto;fillColor=default;gradientColor=none;shadow=0;swimlaneFillColor=default;fontFamily=Times New Roman;fontSize=12;\" value=\"alt\" vertex=\"1\">\n          <mxGeometry height=\"230\" width=\"1940\" x=\"50\" y=\"2430\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-89\" edge=\"1\" parent=\"1\" source=\"OIFvRv84QuahlJDP0eki-88\" style=\"endArrow=none;dashed=1;html=1;rounded=0;exitX=-0.002;exitY=0.519;exitDx=0;exitDy=0;exitPerimeter=0;fontFamily=Times New Roman;fontSize=12;\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"70.00333333333349\" y=\"2544.17\" as=\"sourcePoint\" />\n            <mxPoint x=\"2001.17\" y=\"2544.17\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-90\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;26a: error(Cannot extend - equipment booked immediately after)&lt;/font&gt;\">\n          <mxGeometry relative=\"1\" x=\"-0.01\" y=\"-10\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <Array as=\"points\">\n              <mxPoint x=\"557.42\" y=\"2480\" />\n            </Array>\n            <mxPoint x=\"677.42\" y=\"2480\" as=\"sourcePoint\" />\n            <mxPoint x=\"420.0033333333335\" y=\"2480\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-91\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"26b2: extensionConfirmed(newEndTime, additionalCharge)\">\n          <mxGeometry relative=\"1\" x=\"-0.01\" y=\"-10\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <Array as=\"points\">\n              <mxPoint x=\"557.4166666666665\" y=\"2610\" />\n            </Array>\n            <mxPoint x=\"677.4166666666665\" y=\"2610\" as=\"sourcePoint\" />\n            <mxPoint x=\"420\" y=\"2610\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-92\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"26b_r: extensionConfirmed\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"1809.499999999999\" y=\"2580\" as=\"sourcePoint\" />\n            <mxPoint x=\"710\" y=\"2580\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-93\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1750\" y=\"2620\" />\n            </Array>\n            <mxPoint x=\"710\" y=\"2630\" as=\"sourcePoint\" />\n            <mxPoint x=\"1819.499999999999\" y=\"2630\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-94\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" target=\"LfNKJZrtx-e5gq2OnKBV-3\" value=\"27: display(Reservation extended. New end time set. Extra charge applied.)\">\n          <mxGeometry relative=\"1\" x=\"-0.0223\" y=\"-10\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <Array as=\"points\">\n              <mxPoint x=\"240\" y=\"2730\" />\n            </Array>\n            <mxPoint x=\"750\" y=\"2540\" as=\"sourcePoint\" />\n            <mxPoint x=\"670\" y=\"2540\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-95\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"23: requestExtension(bookingID, additionalHours)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"340\" x=\"90\" y=\"2220\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-96\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;24: checkPostBookingAvailability(equipID, newEndTime)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"320\" x=\"390\" y=\"2250\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-97\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"25: querySchedule(equipID, newEndTime)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"240\" x=\"700\" y=\"2350\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-98\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"[equipment NOT free after current booking]\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"260\" x=\"100\" y=\"2430\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-99\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"equipment IS free\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"110\" x=\"210\" y=\"2520\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-100\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"26b: extendBooking(bookingID, newEndTime)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"250\" x=\"1180\" y=\"2600\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"yv6fUaxiGDH0A_wUmKmq-1\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;\" value=\"&lt;font face=&quot;Times New Roman&quot; style=&quot;font-size: 19px;&quot;&gt;Equipment Reservation &amp;amp; Payment&lt;/font&gt;&lt;div&gt;&lt;font face=&quot;Times New Roman&quot; style=&quot;font-size: 19px;&quot;&gt;[Req3, Req4, Req8, Req9, Req10] - Browse &amp;amp; Reserve | Pay Deposit | Deposit Forfeit&lt;/font&gt;&lt;/div&gt;\" vertex=\"1\">\n          <mxGeometry height=\"40\" width=\"980\" x=\"510\" as=\"geometry\" />\n        </mxCell>\n      </root>\n    </mxGraphModel>\n  </diagram>\n</mxfile>\n"
  },
  {
    "path": "D1/Sequence Diagram/sequence3.drawio",
    "content": "<mxfile host=\"app.diagrams.net\" agent=\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36\" version=\"29.6.0\">\n  <diagram name=\"Page-1\" id=\"2YBvvXClWsGukQMizWep\">\n    <mxGraphModel dx=\"2533\" dy=\"1150\" grid=\"1\" gridSize=\"10\" guides=\"1\" tooltips=\"1\" connect=\"1\" arrows=\"1\" fold=\"1\" page=\"1\" pageScale=\"1\" pageWidth=\"850\" pageHeight=\"1100\" math=\"0\" shadow=\"0\">\n      <root>\n        <mxCell id=\"0\" />\n        <mxCell id=\"1\" parent=\"0\" />\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-3\" parent=\"1\" style=\"shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;dropTarget=0;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\":User (Student/Faculty/ Researcher/Guest\" vertex=\"1\">\n          <mxGeometry height=\"2940\" width=\"180\" x=\"30\" y=\"80\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-4\" parent=\"1\" style=\"shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;dropTarget=0;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\":BookingUI\" vertex=\"1\">\n          <mxGeometry height=\"2930\" width=\"207.5\" x=\"310\" y=\"80\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-10\" parent=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"360\" width=\"30\" x=\"75\" y=\"120\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-2\" parent=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"320\" width=\"15\" x=\"82.5\" y=\"820\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-33\" parent=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"240\" width=\"25\" x=\"77.5\" y=\"1690\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-49\" parent=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"380\" width=\"30\" x=\"85\" y=\"2170\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-5\" parent=\"1\" style=\"shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;dropTarget=0;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\":BookingSystem\" vertex=\"1\">\n          <mxGeometry height=\"2930\" width=\"180\" x=\"590\" y=\"80\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-11\" parent=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"290\" width=\"30\" x=\"75\" y=\"160\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-3\" parent=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"280\" width=\"15\" x=\"80\" y=\"830\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-23\" parent=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"230\" width=\"20\" x=\"77.5\" y=\"1360\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-34\" parent=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"240\" width=\"25\" x=\"80\" y=\"1710\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-50\" parent=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"310\" width=\"30\" x=\"80\" y=\"2200\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-6\" parent=\"1\" style=\"shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;dropTarget=0;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\":EquipmentDatabase\" vertex=\"1\">\n          <mxGeometry height=\"2930\" width=\"180\" x=\"870\" y=\"80\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-12\" parent=\"LfNKJZrtx-e5gq2OnKBV-6\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"160\" width=\"30\" x=\"75\" y=\"190\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-51\" parent=\"LfNKJZrtx-e5gq2OnKBV-6\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"120\" width=\"30\" x=\"75\" y=\"2290\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-7\" parent=\"1\" style=\"shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;dropTarget=0;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\":SensorSystem&lt;div&gt;&amp;lt;&amp;lt;external&amp;gt;&amp;gt;&lt;/div&gt;\" vertex=\"1\">\n          <mxGeometry height=\"2920\" width=\"180\" x=\"1430\" y=\"80\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-24\" parent=\"LfNKJZrtx-e5gq2OnKBV-7\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"80\" width=\"20\" x=\"80\" y=\"1380\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-8\" parent=\"1\" style=\"shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;dropTarget=0;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\":PaymentSystem&lt;div&gt;&amp;lt;&amp;lt;external&amp;gt;&amp;gt;&lt;/div&gt;\" vertex=\"1\">\n          <mxGeometry height=\"2930\" width=\"180\" x=\"1150\" y=\"80\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-4\" parent=\"LfNKJZrtx-e5gq2OnKBV-8\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"150\" width=\"15\" x=\"82.5\" y=\"850\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-9\" parent=\"1\" style=\"shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;dropTarget=0;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\":BookingDatabase\" vertex=\"1\">\n          <mxGeometry height=\"2920\" width=\"180\" x=\"1710\" y=\"80\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-5\" parent=\"LfNKJZrtx-e5gq2OnKBV-9\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"80\" width=\"10\" x=\"80\" y=\"940\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-26\" parent=\"LfNKJZrtx-e5gq2OnKBV-9\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"80\" width=\"10\" x=\"85\" y=\"1490\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-36\" parent=\"LfNKJZrtx-e5gq2OnKBV-9\" style=\"html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};fontFamily=Times New Roman;fontSize=12;\" value=\"\" vertex=\"1\">\n          <mxGeometry height=\"110\" width=\"20\" x=\"80\" y=\"1770\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-14\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-3\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;entryPerimeter=0;fontFamily=Times New Roman;\" target=\"LfNKJZrtx-e5gq2OnKBV-10\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"150\" y=\"210\" />\n            </Array>\n            <mxPoint x=\"120\" y=\"200\" as=\"sourcePoint\" />\n            <mxPoint x=\"280\" y=\"200\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-15\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;entryPerimeter=0;fontFamily=Times New Roman;\" target=\"LfNKJZrtx-e5gq2OnKBV-11\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"460\" y=\"245\" />\n            </Array>\n            <mxPoint x=\"470\" y=\"280\" as=\"sourcePoint\" />\n            <mxPoint x=\"520\" y=\"280\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-17\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;entryPerimeter=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"750\" y=\"270\" />\n            </Array>\n            <mxPoint x=\"690\" y=\"270\" as=\"sourcePoint\" />\n            <mxPoint x=\"955\" y=\"270\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-18\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"LfNKJZrtx-e5gq2OnKBV-6\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"740\" y=\"540\" />\n            </Array>\n            <mxPoint x=\"680\" y=\"540\" as=\"sourcePoint\" />\n            <mxPoint x=\"945\" y=\"540\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-19\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;entryPerimeter=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"470\" y=\"520\" />\n            </Array>\n            <mxPoint x=\"410\" y=\"520\" as=\"sourcePoint\" />\n            <mxPoint x=\"675\" y=\"520\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-20\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;entryPerimeter=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"180\" y=\"480\" />\n            </Array>\n            <mxPoint x=\"120\" y=\"480\" as=\"sourcePoint\" />\n            <mxPoint x=\"385\" y=\"480\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-21\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"4r: display(EquipmentCatalogue)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"200\" y=\"440\" as=\"sourcePoint\" />\n            <mxPoint x=\"120\" y=\"440\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-22\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"4r: equipmentList\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"500\" y=\"400\" as=\"sourcePoint\" />\n            <mxPoint x=\"420\" y=\"400\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-23\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-6\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" target=\"LfNKJZrtx-e5gq2OnKBV-11\" value=\"&lt;font&gt;4r: equipmentList[] (equipID, desc, location, status)&lt;/font&gt;\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"780\" y=\"320\" />\n            </Array>\n            <mxPoint x=\"770\" y=\"360\" as=\"sourcePoint\" />\n            <mxPoint x=\"690\" y=\"360\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-24\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-6\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"7r: status = AVAILABLE&amp;nbsp;\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"760\" y=\"600\" as=\"sourcePoint\" />\n            <mxPoint x=\"680\" y=\"600\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-26\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fillStyle=auto;fillColor=default;gradientColor=none;shadow=0;swimlaneFillColor=default;fontFamily=Times New Roman;fontSize=12;\" value=\"alt\" vertex=\"1\">\n          <mxGeometry height=\"130\" width=\"1040\" x=\"70\" y=\"660\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-27\" edge=\"1\" parent=\"1\" style=\"endArrow=none;dashed=1;html=1;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"69.99666666666674\" y=\"724.33\" as=\"sourcePoint\" />\n            <mxPoint x=\"1110\" y=\"724\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-28\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"7a:error(&#39;Equipment unavailable for selected time&#39;)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"689.5\" y=\"690\" as=\"sourcePoint\" />\n            <mxPoint x=\"410\" y=\"690\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-29\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"7b: availabilityConfirmed(equipID, hourlyRate)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"699.5\" y=\"760\" as=\"sourcePoint\" />\n            <mxPoint x=\"420\" y=\"760\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-32\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-3\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"310\" y=\"840\" />\n            </Array>\n            <mxPoint x=\"250\" y=\"840\" as=\"sourcePoint\" />\n            <mxPoint x=\"400\" y=\"840\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-33\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;b&gt;&lt;u&gt;&lt;font style=&quot;font-size: 14px;&quot;&gt;Section 1: Broswse &amp;amp; Reserve Equipment (Req3, Req4, Req8)&lt;/font&gt;&lt;/u&gt;&lt;/b&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"380\" x=\"30\" y=\"140\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-34\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;1: BrowseEquipment(labLocation, EquipmentType)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"300\" x=\"90\" y=\"170\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-35\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;4:selectEquipment(equipID) + provideStudentID(SID)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"430\" x=\"40\" y=\"450\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-36\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;2: searchAvailableEquipment&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"200\" x=\"440\" y=\"210\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-37\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;5:checkEquipmentAvailability(equipID, startTime, endTime)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"390\" x=\"345\" y=\"490\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-38\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;3: queryAvailablleEquipment(filters)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"220\" x=\"710\" y=\"240\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-39\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;6: getEquipmentStatus(equipID)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"190\" x=\"725\" y=\"510\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-40\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"[equipment not available]\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"210\" x=\"100\" y=\"660\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-41\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"equipment AVAILABLE\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"130\" x=\"200\" y=\"700\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"LfNKJZrtx-e5gq2OnKBV-43\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;8: confirmReservation(equipID, startTime, endTime)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"350\" x=\"90\" y=\"810\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-1\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;b&gt;&lt;u&gt;&lt;font style=&quot;font-size: 14px;&quot;&gt;Section 2 - Pay Deposit Flow (Req4, Req10)&lt;/font&gt;&lt;/u&gt;&lt;/b&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"270\" y=\"860\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-6\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-3\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"OIFvRv84QuahlJDP0eki-2\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"360\" y=\"940\" />\n              <mxPoint x=\"280\" y=\"950\" />\n            </Array>\n            <mxPoint x=\"120\" y=\"1000\" as=\"sourcePoint\" />\n            <mxPoint x=\"280\" y=\"1000\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-7\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;10: selectPayment(CREDIT| DEBIT| YUCARD)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"280\" x=\"115\" y=\"910\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-8\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"LfNKJZrtx-e5gq2OnKBV-5\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"660\" y=\"910\" />\n            </Array>\n            <mxPoint x=\"395.00034482758605\" y=\"900\" as=\"sourcePoint\" />\n            <mxPoint x=\"530\" y=\"890\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-60\" connectable=\"0\" parent=\"OIFvRv84QuahlJDP0eki-8\" style=\"edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontFamily=Times New Roman;fontSize=12;\" value=\"9: calculateDeposit(userType, hourlyRate)\" vertex=\"1\">\n          <mxGeometry relative=\"1\" x=\"-0.7329\" y=\"9\" as=\"geometry\">\n            <mxPoint x=\"107\" y=\"-1\" as=\"offset\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-9\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;10r: depositAmount(Student=$10, Faculty=$15, Researcher=$20, Guest = $30&lt;/font&gt;\">\n          <mxGeometry relative=\"1\" y=\"-10\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <Array as=\"points\">\n              <mxPoint x=\"461.25\" y=\"940\" />\n            </Array>\n            <mxPoint x=\"671.25\" y=\"940\" as=\"sourcePoint\" />\n            <mxPoint x=\"408.75\" y=\"940\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-10\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"OIFvRv84QuahlJDP0eki-3\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"400\" y=\"960\" />\n            </Array>\n            <mxPoint x=\"400\" y=\"960\" as=\"sourcePoint\" />\n            <mxPoint x=\"560\" y=\"970\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-11\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"OIFvRv84QuahlJDP0eki-4\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1240\" y=\"980\" />\n            </Array>\n            <mxPoint x=\"680\" y=\"980\" as=\"sourcePoint\" />\n            <mxPoint x=\"840\" y=\"980\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-12\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fillStyle=auto;fillColor=default;gradientColor=none;shadow=0;swimlaneFillColor=default;fontFamily=Times New Roman;fontSize=12;\" value=\"alt\" vertex=\"1\">\n          <mxGeometry height=\"130\" width=\"1040\" x=\"320\" y=\"1010\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-13\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"13a:paymentFailed(reason)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"1229.5000000000002\" y=\"1040\" as=\"sourcePoint\" />\n            <mxPoint x=\"680\" y=\"1040\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-14\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"13b: paymentConfirmed(transactionID, amount)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"1234.7500000000002\" y=\"1119.66\" as=\"sourcePoint\" />\n            <mxPoint x=\"685.25\" y=\"1119.66\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-15\" edge=\"1\" parent=\"1\" source=\"OIFvRv84QuahlJDP0eki-12\" style=\"endArrow=none;dashed=1;html=1;rounded=0;exitX=0;exitY=0.529;exitDx=0;exitDy=0;exitPerimeter=0;fontFamily=Times New Roman;fontSize=12;\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"339.81034482758605\" y=\"1079.66\" as=\"sourcePoint\" />\n            <mxPoint x=\"1360\" y=\"1079.66\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-16\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"13a2:error(&#39;Payment declined. Try again!&#39;)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"466.5\" y=\"1060\" />\n            </Array>\n            <mxPoint x=\"676\" y=\"1060\" as=\"sourcePoint\" />\n            <mxPoint x=\"434\" y=\"1060\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-18\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"LfNKJZrtx-e5gq2OnKBV-9\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1750\" y=\"1210\" />\n            </Array>\n            <mxPoint x=\"680\" y=\"1170\" as=\"sourcePoint\" />\n            <mxPoint x=\"840\" y=\"1170\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-19\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-9\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" target=\"LfNKJZrtx-e5gq2OnKBV-5\" value=\"15r: bookingID: String\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1020\" y=\"1230\" />\n            </Array>\n            <mxPoint x=\"1100\" y=\"830\" as=\"sourcePoint\" />\n            <mxPoint x=\"1020\" y=\"830\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-20\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" target=\"LfNKJZrtx-e5gq2OnKBV-4\" value=\"15r: bookingConfirmed(bookingID, depositAmt, schedule)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"510\" y=\"1270\" />\n            </Array>\n            <mxPoint x=\"790\" y=\"830\" as=\"sourcePoint\" />\n            <mxPoint x=\"710\" y=\"830\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-21\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" target=\"LfNKJZrtx-e5gq2OnKBV-3\" value=\"15r: display(&#39;Booking confirmed. BookingID returned&#39;)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"260\" y=\"1300\" />\n            </Array>\n            <mxPoint x=\"790\" y=\"830\" as=\"sourcePoint\" />\n            <mxPoint x=\"710\" y=\"830\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-22\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;b&gt;&lt;u&gt;&lt;font style=&quot;font-size: 14px;&quot;&gt;Section 3- Deposit Forfeit on No-Show (Req4)&lt;/font&gt;&lt;/u&gt;&lt;/b&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"290\" x=\"10\" y=\"1340\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-25\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fillStyle=auto;fillColor=default;gradientColor=none;shadow=0;swimlaneFillColor=default;fontFamily=Times New Roman;fontSize=12;\" value=\"opt\" vertex=\"1\">\n          <mxGeometry height=\"150\" width=\"1370\" x=\"570\" y=\"1490\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-27\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-7\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=5;entryPerimeter=0;fontFamily=Times New Roman;\" target=\"OIFvRv84QuahlJDP0eki-23\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1360\" y=\"1445\" />\n            </Array>\n            <mxPoint x=\"1130\" y=\"1450\" as=\"sourcePoint\" />\n            <mxPoint x=\"980\" y=\"1450\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-28\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1695\" y=\"1540\" />\n            </Array>\n            <mxPoint x=\"705\" y=\"1530\" as=\"sourcePoint\" />\n            <mxPoint x=\"1805\" y=\"1530\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-29\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1695\" y=\"1590\" />\n            </Array>\n            <mxPoint x=\"705\" y=\"1580\" as=\"sourcePoint\" />\n            <mxPoint x=\"1805\" y=\"1580\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-30\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"18r: updated\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1035.5\" y=\"1620\" />\n            </Array>\n            <mxPoint x=\"1815.5\" y=\"1620\" as=\"sourcePoint\" />\n            <mxPoint x=\"694.5\" y=\"1620\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-31\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;notify(userID, &#39;Deposit forfeited:no-show after 20 min&#39;)&lt;/font&gt;\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"680.27\" y=\"1670\" as=\"sourcePoint\" />\n            <mxPoint x=\"399.73153846153855\" y=\"1670\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-32\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;b&gt;&lt;u&gt;&lt;font style=&quot;font-size: 14px;&quot;&gt;Section 4 - Modify / Cancel Booking (Req8)&lt;/font&gt;&lt;/u&gt;&lt;/b&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"290\" x=\"-25\" y=\"1710\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-35\" edge=\"1\" parent=\"1\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;curved=0;fontFamily=Times New Roman;fontSize=12;\" value=\"\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"618.75\" y=\"1800\" />\n              <mxPoint x=\"618.75\" y=\"1800\" />\n            </Array>\n            <mxPoint x=\"411.2500000000002\" y=\"1800\" as=\"sourcePoint\" />\n            <mxPoint x=\"668.75\" y=\"1800\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-37\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-5\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" target=\"OIFvRv84QuahlJDP0eki-33\" value=\"21r:bookingStartTime &amp;gt; now -&amp;gt; modifiable\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"520\" y=\"1870\" />\n            </Array>\n            <mxPoint x=\"790\" y=\"1730\" as=\"sourcePoint\" />\n            <mxPoint x=\"710\" y=\"1730\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-40\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-3\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"130\" y=\"1800\" />\n            </Array>\n            <mxPoint x=\"235\" y=\"1780\" as=\"sourcePoint\" />\n            <mxPoint x=\"395\" y=\"1780\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-41\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fillStyle=auto;fillColor=default;gradientColor=none;shadow=0;swimlaneFillColor=default;fontFamily=Times New Roman;fontSize=12;\" value=\"alt\" vertex=\"1\">\n          <mxGeometry height=\"190\" width=\"1940\" x=\"30\" y=\"1910\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-42\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;startArrow=none;startFill=0;endSize=6;startSize=10;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1700.25\" y=\"1960\" />\n            </Array>\n            <mxPoint x=\"690.25\" y=\"1960\" as=\"sourcePoint\" />\n            <mxPoint x=\"1789.75\" y=\"1960\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-43\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;startArrow=none;startFill=0;endSize=6;startSize=10;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1700.25\" y=\"2040\" />\n            </Array>\n            <mxPoint x=\"690.25\" y=\"2040\" as=\"sourcePoint\" />\n            <mxPoint x=\"1789.75\" y=\"2040\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-44\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;startArrow=none;startFill=0;endSize=6;startSize=10;rounded=0;dashed=1;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1565.25\" y=\"2000\" />\n            </Array>\n            <mxPoint x=\"1784.75\" y=\"2000\" as=\"sourcePoint\" />\n            <mxPoint x=\"695.25\" y=\"2000\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-45\" edge=\"1\" parent=\"1\" style=\"endArrow=none;dashed=1;html=1;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"300\" y=\"2040\" />\n            </Array>\n            <mxPoint x=\"690\" y=\"2040\" as=\"sourcePoint\" />\n            <mxPoint x=\"30\" y=\"2040\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-47\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"21a2:modifyConfirmed(bookingID, newSchedule)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"527\" y=\"2020\" />\n            </Array>\n            <mxPoint x=\"687\" y=\"2020\" as=\"sourcePoint\" />\n            <mxPoint x=\"420\" y=\"2020\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-48\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;startArrow=none;startFill=0;endSize=6;startSize=10;rounded=0;dashed=1;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1560\" y=\"2080\" />\n            </Array>\n            <mxPoint x=\"1779.5\" y=\"2080\" as=\"sourcePoint\" />\n            <mxPoint x=\"690\" y=\"2080\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-52\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"440\" y=\"2270\" />\n            </Array>\n            <mxPoint x=\"520\" y=\"2280\" as=\"sourcePoint\" />\n            <mxPoint x=\"680\" y=\"2280\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-53\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-3\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"130\" y=\"2260\" />\n            </Array>\n            <mxPoint x=\"240\" y=\"2250\" as=\"sourcePoint\" />\n            <mxPoint x=\"400\" y=\"2250\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-55\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" target=\"LfNKJZrtx-e5gq2OnKBV-6\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"900\" y=\"2300\" />\n            </Array>\n            <mxPoint x=\"700\" y=\"2380\" as=\"sourcePoint\" />\n            <mxPoint x=\"860\" y=\"2380\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-56\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"26r: noConflict: Boolean\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"955\" y=\"2410\" as=\"sourcePoint\" />\n            <mxPoint x=\"695.5\" y=\"2410\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-59\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;b&gt;&lt;u&gt;&lt;font style=&quot;font-size: 14px;&quot;&gt;Section 5 - Extend Reservation (Req9)&lt;/font&gt;&lt;/u&gt;&lt;/b&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"250\" x=\"-20\" y=\"2170\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-64\" parent=\"1\" style=\"text;whiteSpace=wrap;fontSize=12;fontFamily=Times New Roman;\" value=\"11: initiatePayment(depositAmt, paymentMethod, userID)\" vertex=\"1\">\n          <mxGeometry height=\"20\" width=\"220\" x=\"440\" y=\"940\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-66\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;12: processPayment(depositAmt, paymentDetails)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"270\" x=\"685\" y=\"950\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-67\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;[payment DECLINED]&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"120\" x=\"370\" y=\"1010\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-69\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"payment SUCCESS\" vertex=\"1\">\n          <mxGeometry height=\"20\" width=\"110\" x=\"420\" y=\"1060\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-70\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"14: createBookingRecord(userID, equipID, startTime, depositPaid)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"380\" x=\"1065\" y=\"1140\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-71\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"15: reportUsageStatus(equipID, bookingID, arrivalDetected=FALSE)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"440\" x=\"1010\" y=\"1410\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-73\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"arrivalDetected=FALSE AND elapsed &amp;gt; 20 min\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"260\" x=\"710\" y=\"1500\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-74\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"16:updateDeposit(bookingID, status=&#39;FORFEITED&#39;)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"320\" x=\"1170\" y=\"1500\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-77\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"17: markBookingNoShow(bookingID)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"250\" x=\"1205\" y=\"1550\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-78\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"19: modifyOrCancelBooking(bookingID, action)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"265\" x=\"115\" y=\"1750\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-80\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"20: validateBookingModifiable(bookingID)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"235\" x=\"425\" y=\"1770\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-81\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"[action = MODIFY]\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"110\" x=\"90\" y=\"1910\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-82\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"action = CANCEL\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"110\" x=\"170\" y=\"2010\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-83\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"21a: updateBooking(bookingID, newStartTime, newEndTime)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"460\" x=\"960\" y=\"1930\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-84\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"21a_r: updated\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"355\" x=\"1065\" y=\"1970\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-85\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"21b: cancelBooking(bookingID)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"370\" x=\"1060\" y=\"2010\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-86\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"21b_r: cancelled + refundDeposit\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"200\" x=\"1150\" y=\"2050\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-87\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" target=\"LfNKJZrtx-e5gq2OnKBV-3\" value=\"22: display(&#39;Booking Updated Successfully&#39;)\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"410\" y=\"2150\" as=\"sourcePoint\" />\n            <mxPoint x=\"330\" y=\"2150\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-88\" parent=\"1\" style=\"shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;fillStyle=auto;fillColor=default;gradientColor=none;shadow=0;swimlaneFillColor=default;fontFamily=Times New Roman;fontSize=12;\" value=\"alt\" vertex=\"1\">\n          <mxGeometry height=\"230\" width=\"1940\" x=\"50\" y=\"2430\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-89\" edge=\"1\" parent=\"1\" source=\"OIFvRv84QuahlJDP0eki-88\" style=\"endArrow=none;dashed=1;html=1;rounded=0;exitX=-0.002;exitY=0.519;exitDx=0;exitDy=0;exitPerimeter=0;fontFamily=Times New Roman;fontSize=12;\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <mxPoint x=\"70.00333333333349\" y=\"2544.17\" as=\"sourcePoint\" />\n            <mxPoint x=\"2001.17\" y=\"2544.17\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-90\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;26a: error(Cannot extend - equipment booked immediately after)&lt;/font&gt;\">\n          <mxGeometry relative=\"1\" x=\"-0.01\" y=\"-10\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <Array as=\"points\">\n              <mxPoint x=\"557.42\" y=\"2480\" />\n            </Array>\n            <mxPoint x=\"677.42\" y=\"2480\" as=\"sourcePoint\" />\n            <mxPoint x=\"420.0033333333335\" y=\"2480\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-91\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"26b2: extensionConfirmed(newEndTime, additionalCharge)\">\n          <mxGeometry relative=\"1\" x=\"-0.01\" y=\"-10\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <Array as=\"points\">\n              <mxPoint x=\"557.4166666666665\" y=\"2610\" />\n            </Array>\n            <mxPoint x=\"677.4166666666665\" y=\"2610\" as=\"sourcePoint\" />\n            <mxPoint x=\"420\" y=\"2610\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-92\" edge=\"1\" parent=\"1\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"26b_r: extensionConfirmed\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"1809.499999999999\" y=\"2580\" as=\"sourcePoint\" />\n            <mxPoint x=\"710\" y=\"2580\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-93\" edge=\"1\" parent=\"1\" style=\"edgeStyle=elbowEdgeStyle;fontSize=12;html=1;endArrow=blockThin;endFill=1;rounded=0;fontFamily=Times New Roman;\" value=\"\">\n          <mxGeometry relative=\"1\" width=\"160\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"1750\" y=\"2620\" />\n            </Array>\n            <mxPoint x=\"710\" y=\"2630\" as=\"sourcePoint\" />\n            <mxPoint x=\"1819.499999999999\" y=\"2630\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-94\" edge=\"1\" parent=\"1\" source=\"LfNKJZrtx-e5gq2OnKBV-4\" style=\"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;fontFamily=Times New Roman;fontSize=12;\" target=\"LfNKJZrtx-e5gq2OnKBV-3\" value=\"27: display(Reservation extended. New end time set. Extra charge applied.)\">\n          <mxGeometry relative=\"1\" x=\"-0.0223\" y=\"-10\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <Array as=\"points\">\n              <mxPoint x=\"240\" y=\"2730\" />\n            </Array>\n            <mxPoint x=\"750\" y=\"2540\" as=\"sourcePoint\" />\n            <mxPoint x=\"670\" y=\"2540\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-95\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"23: requestExtension(bookingID, additionalHours)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"340\" x=\"90\" y=\"2220\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-96\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"&lt;font&gt;24: checkPostBookingAvailability(equipID, newEndTime)&lt;/font&gt;\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"320\" x=\"390\" y=\"2250\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-97\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"25: querySchedule(equipID, newEndTime)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"240\" x=\"700\" y=\"2350\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-98\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"[equipment NOT free after current booking]\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"260\" x=\"100\" y=\"2430\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-99\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"equipment IS free\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"110\" x=\"210\" y=\"2520\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"OIFvRv84QuahlJDP0eki-100\" parent=\"1\" style=\"text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontFamily=Times New Roman;fontSize=12;\" value=\"26b: extendBooking(bookingID, newEndTime)\" vertex=\"1\">\n          <mxGeometry height=\"30\" width=\"250\" x=\"1180\" y=\"2600\" as=\"geometry\" />\n        </mxCell>\n      </root>\n    </mxGraphModel>\n  </diagram>\n</mxfile>\n"
  },
  {
    "path": "D2/.vscode/settings.json",
    "content": "{\n  \"java.project.referencedLibraries\": [\n    \"lib/**/*.jar\"\n  ]\n}"
  },
  {
    "path": "D2/data/bookings.csv",
    "content": "bookingID,userID,equipmentID,startTime,endTime,status,depositAmount,depositForfeited,paymentMethod,isExtended\nB001,U001,EQ001,2026-03-20 09:00,2026-03-20 11:00,CONFIRMED,10.0,false,CREDIT,false\nB002,U002,EQ004,2026-03-21 14:00,2026-03-21 16:00,CONFIRMED,15.0,false,INSTITUTIONAL,false\n"
  },
  {
    "path": "D2/data/equipment.csv",
    "content": "equipmentID,name,description,type,status,buildingName,roomNumber\nEQ001,Oscilloscope,Digital oscilloscope 200MHz,Electronics,AVAILABLE,Lassonde,101\nEQ002,3D Printer,FDM 3D printer,Fabrication,AVAILABLE,Bergeron,202\nEQ003,Laser Cutter,CO2 laser cutter,Fabrication,MAINTENANCE,Lassonde,103\nEQ004,Spectrometer,UV-Vis spectrometer,Optics,AVAILABLE,Petrie,305\nEQ005,CNC Machine,3-axis CNC milling machine,Fabrication,DISABLED,Bergeron,204\n"
  },
  {
    "path": "D2/data/users.csv",
    "content": "userID,name,email,password,userType,staffID,status,department\nU001,Alice Student,alice@yorku.ca,pass123,STUDENT,S12345,ACTIVE,Engineering\nU002,Bob Faculty,bob@yorku.ca,pass123,FACULTY,F67890,ACTIVE,Science\nU003,Carol Researcher,carol@yorku.ca,pass123,RESEARCHER,R11111,ACTIVE,Research\nU004,Dave Guest,dave@example.com,pass123,GUEST,CERT-999,ACTIVE,External\nM001,Manager Mike,manager@yorku.ca,manager123,MANAGER,MGR-001,ACTIVE,Engineering\nC001,Coordinator Carol,coord@yorku.ca,coord123,COORDINATOR,COORD-001,ACTIVE,Administration\nU1773892952781,shiah,shiah@gmail.com,Ilham123,STUDENT,123,PENDING,eecs\nU1773922455105,Jane Doe,jane@yorku.ca,pass123,FACULTY,S12345,PENDING,Engineering\n"
  },
  {
    "path": "D2/src/Main.java",
    "content": "import javax.swing.SwingUtilities;\nimport gui.MainFrame;\n\npublic class Main {\n    public static void main(String[] args) {\n        SwingUtilities.invokeLater(() -> {\n            MainFrame.getInstance().setVisible(true);\n        });\n    }\n}\n"
  },
  {
    "path": "D2/src/data/.gitkeep",
    "content": ""
  },
  {
    "path": "D2/src/data/BookingDAO.java",
    "content": "package data;\n\nimport com.csvreader.CsvReader;\nimport com.csvreader.CsvWriter;\nimport model.Reservation;\n\nimport java.io.FileWriter;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * BookingDAO - loads and saves reservations from/to bookings.csv\n * CSV columns: bookingID,userID,equipmentID,startTime,endTime,status,depositAmount,depositForfeited,paymentMethod,isExtended\n */\npublic class BookingDAO {\n\n    private String path;\n    private List<Reservation> bookings = new ArrayList<>();\n\n    public BookingDAO(String path) {\n        this.path = path;\n    }\n\n    public void load() throws Exception {\n        bookings.clear();\n        CsvReader reader = new CsvReader(path);\n        reader.readHeaders();\n\n        while (reader.readRecord()) {\n            Reservation r = new Reservation();\n            r.setBookingID(reader.get(\"bookingID\"));\n            r.setUserID(reader.get(\"userID\"));\n            r.setEquipmentID(reader.get(\"equipmentID\"));\n            r.setStartTime(reader.get(\"startTime\"));\n            r.setEndTime(reader.get(\"endTime\"));\n            r.setStatus(reader.get(\"status\"));\n            r.setDepositAmount(Double.parseDouble(reader.get(\"depositAmount\")));\n            r.setDepositForfeited(Boolean.parseBoolean(reader.get(\"depositForfeited\")));\n            r.setPaymentMethod(reader.get(\"paymentMethod\"));\n            r.setExtended(Boolean.parseBoolean(reader.get(\"isExtended\")));\n            bookings.add(r);\n        }\n        reader.close();\n    }\n\n    public void save() throws Exception {\n        CsvWriter writer = new CsvWriter(new FileWriter(path, false), ',');\n\n        writer.write(\"bookingID\");\n        writer.write(\"userID\");\n        writer.write(\"equipmentID\");\n        writer.write(\"startTime\");\n        writer.write(\"endTime\");\n        writer.write(\"status\");\n        writer.write(\"depositAmount\");\n        writer.write(\"depositForfeited\");\n        writer.write(\"paymentMethod\");\n        writer.write(\"isExtended\");\n        writer.endRecord();\n\n        for (Reservation r : bookings) {\n            writer.write(r.getBookingID());\n            writer.write(r.getUserID());\n            writer.write(r.getEquipmentID());\n            writer.write(r.getStartTime());\n            writer.write(r.getEndTime());\n            writer.write(r.getStatus());\n            writer.write(String.valueOf(r.getDepositAmount()));\n            writer.write(String.valueOf(r.isDepositForfeited()));\n            writer.write(r.getPaymentMethod());\n            writer.write(String.valueOf(r.isExtended()));\n            writer.endRecord();\n        }\n        writer.close();\n    }\n\n    public void addBooking(Reservation r) {\n        bookings.add(r);\n    }\n\n    public Reservation findByID(String bookingID) {\n        for (Reservation r : bookings) {\n            if (r.getBookingID().equals(bookingID)) return r;\n        }\n        return null;\n    }\n\n    public List<Reservation> getBookingsByUser(String userID) {\n        List<Reservation> result = new ArrayList<>();\n        for (Reservation r : bookings) {\n            if (r.getUserID().equals(userID)) result.add(r);\n        }\n        return result;\n    }\n\n    public List<Reservation> getBookingsByEquipment(String equipmentID) {\n        List<Reservation> result = new ArrayList<>();\n        for (Reservation r : bookings) {\n            if (r.getEquipmentID().equals(equipmentID)) result.add(r);\n        }\n        return result;\n    }\n\n    public List<Reservation> getAllBookings() {\n        return bookings;\n    }\n\n    public void updateBooking(Reservation updated) {\n        for (int i = 0; i < bookings.size(); i++) {\n            if (bookings.get(i).getBookingID().equals(updated.getBookingID())) {\n                bookings.set(i, updated);\n                return;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "D2/src/data/EquipmentDAO.java",
    "content": "package data;\n\nimport com.csvreader.CsvReader;\nimport com.csvreader.CsvWriter;\nimport model.Equipment;\n\nimport java.io.FileWriter;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * EquipmentDAO - loads and saves equipment from/to equipment.csv\n * CSV columns: equipmentID,name,description,type,status,buildingName,roomNumber\n */\npublic class EquipmentDAO {\n\n    private String path;\n    private List<Equipment> equipmentList = new ArrayList<>();\n\n    public EquipmentDAO(String path) {\n        this.path = path;\n    }\n\n    public void load() throws Exception {\n        equipmentList.clear();\n        CsvReader reader = new CsvReader(path);\n        reader.readHeaders();\n\n        while (reader.readRecord()) {\n            Equipment e = new Equipment();\n            e.setEquipmentID(reader.get(\"equipmentID\"));\n            e.setName(reader.get(\"name\"));\n            e.setDescription(reader.get(\"description\"));\n            e.setType(reader.get(\"type\"));\n            e.setStatus(reader.get(\"status\"));\n            e.setBuildingName(reader.get(\"buildingName\"));\n            e.setRoomNumber(reader.get(\"roomNumber\"));\n            equipmentList.add(e);\n        }\n        reader.close();\n    }\n\n    public void save() throws Exception {\n        CsvWriter writer = new CsvWriter(new FileWriter(path, false), ',');\n\n        writer.write(\"equipmentID\");\n        writer.write(\"name\");\n        writer.write(\"description\");\n        writer.write(\"type\");\n        writer.write(\"status\");\n        writer.write(\"buildingName\");\n        writer.write(\"roomNumber\");\n        writer.endRecord();\n\n        for (Equipment e : equipmentList) {\n            writer.write(e.getEquipmentID());\n            writer.write(e.getName());\n            writer.write(e.getDescription());\n            writer.write(e.getType());\n            writer.write(e.getStatus());\n            writer.write(e.getBuildingName());\n            writer.write(e.getRoomNumber());\n            writer.endRecord();\n        }\n        writer.close();\n    }\n\n    public void addEquipment(Equipment e) {\n        equipmentList.add(e);\n    }\n\n    public Equipment findByID(String equipmentID) {\n        for (Equipment e : equipmentList) {\n            if (e.getEquipmentID().equals(equipmentID)) return e;\n        }\n        return null;\n    }\n\n    public List<Equipment> getAllEquipment() {\n        return equipmentList;\n    }\n\n    public List<Equipment> getAvailableEquipment() {\n        List<Equipment> available = new ArrayList<>();\n        for (Equipment e : equipmentList) {\n            if (e.isAvailable()) available.add(e);\n        }\n        return available;\n    }\n\n    public void updateEquipment(Equipment updated) {\n        for (int i = 0; i < equipmentList.size(); i++) {\n            if (equipmentList.get(i).getEquipmentID().equals(updated.getEquipmentID())) {\n                equipmentList.set(i, updated);\n                return;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "D2/src/data/UserDAO.java",
    "content": "package data;\n\nimport com.csvreader.CsvReader;\nimport com.csvreader.CsvWriter;\nimport model.*;\n\nimport java.io.FileWriter;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * UserDAO - loads and saves users from/to users.csv\n * CSV columns: userID,name,email,password,userType,staffID,status,department\n */\npublic class UserDAO {\n\n    private String path;\n    private List<User> users = new ArrayList<>();\n\n    public UserDAO(String path) {\n        this.path = path;\n    }\n\n    public void load() throws Exception {\n        users.clear();\n        CsvReader reader = new CsvReader(path);\n        reader.readHeaders();\n\n        while (reader.readRecord()) {\n            String userType = reader.get(\"userType\");\n            User user = createUser(userType);\n\n            user.setUserID(reader.get(\"userID\"));\n            user.setName(reader.get(\"name\"));\n            user.setEmail(reader.get(\"email\"));\n            user.setPassword(reader.get(\"password\"));\n            user.setUserType(userType);\n            user.setStaffID(reader.get(\"staffID\"));\n            user.setStatus(reader.get(\"status\"));\n            user.setDepartment(reader.get(\"department\"));\n\n            users.add(user);\n        }\n        reader.close();\n    }\n\n    public void save() throws Exception {\n        CsvWriter writer = new CsvWriter(new FileWriter(path, false), ',');\n\n        // Write headers\n        writer.write(\"userID\");\n        writer.write(\"name\");\n        writer.write(\"email\");\n        writer.write(\"password\");\n        writer.write(\"userType\");\n        writer.write(\"staffID\");\n        writer.write(\"status\");\n        writer.write(\"department\");\n        writer.endRecord();\n\n        // Write each user\n        for (User u : users) {\n            writer.write(u.getUserID());\n            writer.write(u.getName());\n            writer.write(u.getEmail());\n            writer.write(u.getPassword());\n            writer.write(u.getUserType());\n            writer.write(u.getStaffID());\n            writer.write(u.getStatus());\n            writer.write(u.getDepartment());\n            writer.endRecord();\n        }\n        writer.close();\n    }\n\n    public void addUser(User user) {\n        users.add(user);\n    }\n\n    public User findByEmail(String email) {\n        for (User u : users) {\n            if (u.getEmail().equalsIgnoreCase(email)) return u;\n        }\n        return null;\n    }\n\n    public User findByID(String userID) {\n        for (User u : users) {\n            if (u.getUserID().equals(userID)) return u;\n        }\n        return null;\n    }\n\n    public boolean emailExists(String email) {\n        return findByEmail(email) != null;\n    }\n\n    public List<User> getAllUsers() {\n        return users;\n    }\n\n    public void updateUser(User updated) {\n        for (int i = 0; i < users.size(); i++) {\n            if (users.get(i).getUserID().equals(updated.getUserID())) {\n                users.set(i, updated);\n                return;\n            }\n        }\n    }\n\n    // Factory helper - creates the right subclass based on userType string\n    private User createUser(String userType) {\n        switch (userType.toUpperCase()) {\n            case \"STUDENT\":    return new Student();\n            case \"FACULTY\":    return new Faculty();\n            case \"RESEARCHER\": return new Researcher();\n            case \"GUEST\":      return new Guest();\n            case \"MANAGER\":    return new LabManager();\n            case \"COORDINATOR\": return new HeadLabCoordinator();\n            default:           return new Student();\n        }\n    }\n}\n"
  },
  {
    "path": "D2/src/gui/.gitkeep",
    "content": ""
  },
  {
    "path": "D2/src/gui/CoordinatorDashboardPanel.java",
    "content": "package gui;\n\nimport javax.swing.*;\nimport javax.swing.table.*;\nimport java.awt.*;\nimport data.UserDAO;\nimport model.*;\nimport pattern.singleton.HeadLabCoordinatorSingleton;\n\npublic class CoordinatorDashboardPanel extends ManagerDashboardPanel {\n    private static final long serialVersionUID = 1L;\n\n    private DefaultTableModel allUsersModel;\n    private JTable allUsersTable;\n    private JTextField genID, genName, genEmail, genDept;\n    private JLabel coordInfo;\n\n    public CoordinatorDashboardPanel(MainFrame frame) {\n        super(frame, false); // don't call build() yet\n        build();\n    }\n\n    @Override\n    public void refresh() {\n        try { equipDAO.load(); userDAO.load(); bookDAO.load(); } catch (Exception e) { e.printStackTrace(); }\n        if (currentUser != null && coordInfo != null)\n            coordInfo.setText(\"  Head Lab Coordinator  |  \" + currentUser.getName());\n        refreshEquip();\n        refreshPending();\n        refreshAllBookings();\n        refreshAllUsers();\n    }\n\n    @Override\n    protected void build() {\n        setBackground(UI.BG);\n        setLayout(new BorderLayout());\n\n        JButton logout = UI.button(\"Logout\", UI.DANGER);\n        logout.addActionListener(e -> getFrame().showPanel(MainFrame.LOGIN));\n        coordInfo = new JLabel(\"  \");\n        coordInfo.setForeground(new Color(148,163,184));\n        coordInfo.setFont(new Font(\"SansSerif\", Font.PLAIN, 12));\n        JPanel nav = UI.navBar(\"👑 Coordinator Console\", \"\", logout);\n        nav.add(coordInfo, BorderLayout.CENTER);\n        add(nav, BorderLayout.NORTH);\n\n        JTabbedPane tabs = new JTabbedPane();\n        tabs.setFont(new Font(\"SansSerif\", Font.BOLD, 12));\n        tabs.addTab(\"⚠ Pending Approvals\", buildPendingTab());\n        tabs.addTab(\"🔬 Equipment\",         buildEquipTab());\n        tabs.addTab(\"➕ Add Equipment\",     buildAddTab());\n        tabs.addTab(\"📋 All Bookings\",      buildBookingsTab());\n        tabs.addTab(\"👥 All Users\",         buildAllUsersTab());\n        tabs.addTab(\"🔑 Generate Manager\",  buildGenerateTab());\n        add(tabs, BorderLayout.CENTER);\n\n        status = UI.statusBar();\n        add(status, BorderLayout.SOUTH);\n    }\n\n    private JPanel buildAllUsersTab() {\n        JPanel p = new JPanel(new BorderLayout(10, 10));\n        p.setBackground(UI.BG);\n        p.setBorder(BorderFactory.createEmptyBorder(14, 14, 14, 14));\n        p.add(UI.heading(\"All Registered Users\"), BorderLayout.NORTH);\n\n        allUsersModel = UI.tableModel(\"User ID\",\"Name\",\"Email\",\"Type\",\"Staff ID\",\"Department\",\"Status\");\n        allUsersTable = UI.styledTable(allUsersModel);\n        p.add(new JScrollPane(allUsersTable), BorderLayout.CENTER);\n\n        JPanel btns = new JPanel(new FlowLayout(FlowLayout.LEFT, 8, 8));\n        btns.setBackground(UI.BG);\n        JButton refresh = UI.button(\"↻ Refresh\", UI.YORKU_RED);\n        refresh.addActionListener(e -> refreshAllUsers());\n\n        JButton approve = UI.button(\"✔ Approve Selected\", UI.SUCCESS);\n        approve.addActionListener(e -> approveFromAllUsers());\n\n        JButton reject = UI.button(\"✘ Reject Selected\", UI.DANGER);\n        reject.addActionListener(e -> rejectFromAllUsers());\n\n        btns.add(refresh); btns.add(approve); btns.add(reject);\n        p.add(btns, BorderLayout.SOUTH);\n        return p;\n    }\n\n    private JPanel buildGenerateTab() {\n        JPanel outer = new JPanel(new GridBagLayout());\n        outer.setBackground(UI.BG);\n\n        JPanel form = UI.card(\"Generate Lab Manager Account (Req2)\");\n\n        JLabel note = new JLabel(\"Only the Head Lab Coordinator can perform this action (Req2).\");\n        note.setFont(new Font(\"SansSerif\", Font.ITALIC, 12));\n        note.setForeground(UI.TEXT_MUTED);\n        note.setAlignmentX(Component.LEFT_ALIGNMENT);\n        form.add(note);\n        form.add(Box.createVerticalStrut(12));\n\n        genID    = addField(form, \"Manager ID (e.g. M002)\");\n        genName  = addField(form, \"Full Name\");\n        genEmail = addField(form, \"Email Address\");\n        genDept  = addField(form, \"Department\");\n\n        form.add(Box.createVerticalStrut(8));\n        JButton gen = UI.button(\"Generate Manager Account\", UI.YORKU_RED);\n        gen.setAlignmentX(Component.LEFT_ALIGNMENT);\n        gen.addActionListener(e -> generateManager());\n        form.add(gen);\n\n        JPanel wrap = new JPanel(new BorderLayout());\n        wrap.setBackground(UI.CARD);\n        wrap.setBorder(BorderFactory.createLineBorder(UI.BORDER));\n        wrap.add(form, BorderLayout.CENTER);\n        outer.add(wrap);\n        return outer;\n    }\n\n    private void refreshAllUsers() {\n        if (allUsersModel == null) return;\n        try { userDAO.load(); } catch (Exception e) { e.printStackTrace(); }\n        allUsersModel.setRowCount(0);\n        for (User u : userDAO.getAllUsers())\n            allUsersModel.addRow(new Object[]{\n                u.getUserID(), u.getName(), u.getEmail(),\n                u.getUserType(), u.getStaffID(), u.getDepartment(), u.getStatus()\n            });\n    }\n\n    private void approveFromAllUsers() {\n        int row = allUsersTable.getSelectedRow();\n        if (row < 0) { UI.setStatus(status, \"Select a user.\", true); return; }\n        String uid  = (String) allUsersModel.getValueAt(row, 0);\n        String name = (String) allUsersModel.getValueAt(row, 1);\n        User u = userDAO.findByID(uid);\n        if (u == null) return;\n        u.setStatus(\"ACTIVE\");\n        userDAO.updateUser(u);\n        try { userDAO.save(); } catch (Exception e) { e.printStackTrace(); }\n        UI.setStatus(status, \"✔ Approved: \" + name, false);\n        refreshAllUsers(); refreshPending();\n    }\n\n    private void rejectFromAllUsers() {\n        int row = allUsersTable.getSelectedRow();\n        if (row < 0) { UI.setStatus(status, \"Select a user.\", true); return; }\n        String uid  = (String) allUsersModel.getValueAt(row, 0);\n        String name = (String) allUsersModel.getValueAt(row, 1);\n        User u = userDAO.findByID(uid);\n        if (u == null) return;\n        u.setStatus(\"REJECTED\");\n        userDAO.updateUser(u);\n        try { userDAO.save(); } catch (Exception e) { e.printStackTrace(); }\n        UI.setStatus(status, \"✘ Rejected: \" + name, false);\n        refreshAllUsers(); refreshPending();\n    }\n\n    private void generateManager() {\n        if (currentUser == null || !\"COORDINATOR\".equals(currentUser.getUserType())) {\n            UI.setStatus(status, \"Only the Head Lab Coordinator can do this (Req2).\", true); return;\n        }\n        String id   = genID.getText().trim();\n        String name = genName.getText().trim();\n        String email = genEmail.getText().trim();\n        String dept = genDept.getText().trim();\n        if (id.isEmpty() || name.isEmpty() || email.isEmpty()) {\n            UI.setStatus(status, \"All fields required.\", true); return;\n        }\n        try { userDAO.load(); } catch (Exception e) { e.printStackTrace(); }\n        if (userDAO.emailExists(email)) {\n            UI.setStatus(status, \"Email already exists.\", true); return;\n        }\n\n        String tempPass = \"temp\" + id;\n        LabManager mgr = HeadLabCoordinatorSingleton.getInstance()\n            .generateManagerAccount(id, name, email, tempPass, dept);\n        userDAO.addUser(mgr);\n        try { userDAO.save(); } catch (Exception e) { e.printStackTrace(); }\n\n        UI.setStatus(status,\n            \"✔ Manager account created! Email: \" + email + \"  |  Temp Password: \" + tempPass, false);\n        genID.setText(\"\"); genName.setText(\"\"); genEmail.setText(\"\"); genDept.setText(\"\");\n        refreshAllUsers();\n    }\n\n    private MainFrame getFrame() {\n        Container c = getParent();\n        while (c != null && !(c instanceof MainFrame)) c = c.getParent();\n        return (MainFrame) c;\n    }\n}\n"
  },
  {
    "path": "D2/src/gui/LoginPanel.java",
    "content": "package gui;\n\nimport javax.swing.*;\nimport javax.swing.border.*;\nimport java.awt.*;\nimport data.UserDAO;\nimport model.User;\nimport pattern.factory.UserFactory;\n\npublic class LoginPanel extends JPanel {\n    private static final long serialVersionUID = 1L;\n    private MainFrame frame;\n    private UserDAO userDAO = new UserDAO(\"data/users.csv\");\n    private JTextField emailField;\n    private JPasswordField passField;\n    private JTextField regName, regEmail, regStaffID, regDept;\n    private JPasswordField regPass;\n    private JComboBox<String> regType;\n    private JLabel status;\n\n    public LoginPanel(MainFrame frame) {\n        this.frame = frame;\n        try { userDAO.load(); } catch (Exception e) { e.printStackTrace(); }\n        build();\n    }\n\n    private void build() {\n        setBackground(UI.BG);\n        setLayout(new BorderLayout());\n\n        // Nav bar\n        JPanel nav = new JPanel(new BorderLayout());\n        nav.setBackground(UI.NAV_BG);\n        nav.setBorder(BorderFactory.createMatteBorder(0, 0, 4, 0, UI.YORKU_RED));\n        JPanel navLeft = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));\n        navLeft.setBackground(UI.NAV_BG);\n        JLabel badge = new JLabel(\"  Y  \");\n        badge.setFont(new Font(\"Segoe UI\", Font.BOLD, 15));\n        badge.setForeground(Color.WHITE); badge.setBackground(UI.YORKU_RED); badge.setOpaque(true);\n        badge.setBorder(BorderFactory.createEmptyBorder(13,14,13,14));\n        JLabel title = new JLabel(\"  YorkU Lab Equipment Reservation System\");\n        title.setFont(UI.F_HEAD); title.setForeground(UI.NAV_FG);\n        navLeft.add(badge); navLeft.add(title);\n        nav.add(navLeft, BorderLayout.WEST);\n        add(nav, BorderLayout.NORTH);\n\n        // Cards\n        JPanel centre = new JPanel(new GridBagLayout());\n        centre.setBackground(UI.BG);\n        JPanel cards = new JPanel(new GridLayout(1, 2, 24, 0));\n        cards.setBackground(UI.BG);\n        cards.setPreferredSize(new Dimension(940, 560));\n        cards.add(buildLoginCard());\n        cards.add(buildRegCard());\n        centre.add(cards);\n        add(centre, BorderLayout.CENTER);\n\n        // Status\n        status = UI.statusBar();\n        status.setText(\"  Welcome — please sign in or create an account.\");\n        add(status, BorderLayout.SOUTH);\n    }\n\n    private JPanel buildLoginCard() {\n        JPanel inner = UI.card(\"Sign In\");\n        inner.add(UI.label(\"Email address\")); inner.add(Box.createVerticalStrut(4));\n        emailField = UI.field(\"alice@yorku.ca\"); inner.add(emailField);\n        inner.add(Box.createVerticalStrut(14));\n        inner.add(UI.label(\"Password\")); inner.add(Box.createVerticalStrut(4));\n        passField = UI.password();\n        passField.setMaximumSize(new Dimension(Integer.MAX_VALUE, 36));\n        passField.setAlignmentX(Component.LEFT_ALIGNMENT);\n        inner.add(passField); inner.add(Box.createVerticalStrut(22));\n\n        JButton btn = UI.primary(\"Login\");\n        btn.setMaximumSize(new Dimension(Integer.MAX_VALUE, 42));\n        btn.setAlignmentX(Component.LEFT_ALIGNMENT);\n        btn.addActionListener(e -> handleLogin());\n        inner.add(btn); inner.add(Box.createVerticalStrut(20));\n\n        // Red hint box\n        JPanel hint = new JPanel();\n        hint.setLayout(new BoxLayout(hint, BoxLayout.Y_AXIS));\n        hint.setBackground(new Color(0xfb, 0xe9, 0xec));\n        hint.setBorder(BorderFactory.createCompoundBorder(\n            new LineBorder(new Color(0xe3,0x18,0x37,80), 1, true),\n            BorderFactory.createEmptyBorder(10,12,10,12)));\n        hint.setAlignmentX(Component.LEFT_ALIGNMENT);\n        hint.setMaximumSize(new Dimension(Integer.MAX_VALUE, 130));\n        JLabel ht = new JLabel(\"Test Accounts\"); ht.setFont(UI.F_SUB);\n        ht.setForeground(UI.YORKU_DARK); ht.setAlignmentX(Component.LEFT_ALIGNMENT);\n        hint.add(ht); hint.add(Box.createVerticalStrut(6));\n        for (String line : new String[]{\n            \"alice@yorku.ca / pass123  →  Student\",\n            \"bob@yorku.ca / pass123  →  Faculty\",\n            \"manager@yorku.ca / manager123  →  Manager\",\n            \"coord@yorku.ca / coord123  →  Coordinator\"}) {\n            JLabel l = new JLabel(line); l.setFont(UI.F_SMALL); l.setForeground(UI.TEXT_MUTED);\n            l.setAlignmentX(Component.LEFT_ALIGNMENT); hint.add(l);\n        }\n        inner.add(hint);\n        return wrapCard(inner);\n    }\n\n    private JPanel buildRegCard() {\n        JPanel inner = UI.card(\"Create Account\");\n        regName    = UI.formField(inner, \"Full Name\");\n        regEmail   = UI.formField(inner, \"Email Address\");\n        regPass    = UI.formPassword(inner, \"Password (min 6 characters)\");\n        regType    = UI.formCombo(inner, \"User Type\", \"STUDENT\",\"FACULTY\",\"RESEARCHER\",\"GUEST\");\n        regStaffID = UI.formField(inner, \"Staff / Student ID or Certification Number (Req8)\");\n        regDept    = UI.formField(inner, \"Department\");\n        JButton btn = UI.primary(\"Create Account\");\n        btn.setMaximumSize(new Dimension(Integer.MAX_VALUE, 42));\n        btn.setAlignmentX(Component.LEFT_ALIGNMENT);\n        btn.addActionListener(e -> handleRegister());\n        inner.add(btn);\n        return wrapCard(inner);\n    }\n\n    private JPanel wrapCard(JPanel inner) {\n        JPanel w = new JPanel(new BorderLayout());\n        w.setBackground(UI.CARD);\n        w.setBorder(BorderFactory.createCompoundBorder(\n            new LineBorder(UI.BORDER, 1, true),\n            BorderFactory.createEmptyBorder(26, 30, 26, 30)));\n        w.add(inner); return w;\n    }\n\n    private void handleLogin() {\n        String email = emailField.getText().trim();\n        String pass  = new String(passField.getPassword()).trim();\n        if (email.isEmpty() || pass.isEmpty()) { setStatus(\"Please enter your email and password.\", true); return; }\n        try { userDAO.load(); } catch (Exception e) { e.printStackTrace(); }\n        User user = userDAO.findByEmail(email);\n        if (user == null || !user.getPassword().equals(pass)) { setStatus(\"Invalid email or password.\", true); return; }\n        if (\"PENDING\".equals(user.getStatus()))  { setStatus(\"Account is pending departmental approval.\", true); return; }\n        if (\"REJECTED\".equals(user.getStatus())) { setStatus(\"Account was rejected. Contact the coordinator.\", true); return; }\n        setStatus(\"Welcome, \" + user.getName() + \"!\", false);\n        frame.onLoginSuccess(user);\n    }\n\n    private void handleRegister() {\n        String name=regName.getText().trim(), email=regEmail.getText().trim();\n        String pass=new String(regPass.getPassword()).trim(), type=(String)regType.getSelectedItem();\n        String staffID=regStaffID.getText().trim(), dept=regDept.getText().trim();\n        if (name.isEmpty()||email.isEmpty()||pass.isEmpty()||staffID.isEmpty()) { setStatus(\"All fields are required.\", true); return; }\n        if (pass.length()<6) { setStatus(\"Password must be at least 6 characters.\", true); return; }\n        try { userDAO.load(); } catch (Exception e) { e.printStackTrace(); }\n        if (userDAO.emailExists(email)) { setStatus(\"Email is already registered.\", true); return; }\n        UserFactory factory = new UserFactory();\n        User u = factory.getUserType(type);\n        u.setUserID(\"U\"+System.currentTimeMillis()); u.setName(name); u.setEmail(email);\n        u.setPassword(pass); u.setUserType(type); u.setStaffID(staffID); u.setDepartment(dept);\n        u.setStatus(\"GUEST\".equals(type)?\"ACTIVE\":\"PENDING\");\n        userDAO.addUser(u);\n        try { userDAO.save(); } catch (Exception e) { setStatus(\"Error saving account.\",true); return; }\n        setStatus(\"GUEST\".equals(type)?\"Account created! You can now sign in.\":\"Registration submitted — awaiting departmental approval.\", false);\n        regName.setText(\"\"); regEmail.setText(\"\"); regPass.setText(\"\"); regStaffID.setText(\"\"); regDept.setText(\"\");\n    }\n\n    private void setStatus(String msg, boolean error) {\n        status.setText(\"  \"+msg);\n        status.setForeground(error ? UI.DANGER : UI.SUCCESS);\n    }\n}\n"
  },
  {
    "path": "D2/src/gui/MainFrame.java",
    "content": "package gui;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport model.User;\n\npublic class MainFrame extends JFrame {\n\n    private static final long serialVersionUID = 1L;\n    private static MainFrame instance;\n\n    private CardLayout cardLayout;\n    private JPanel mainPanel;\n\n    private LoginPanel loginPanel;\n    private UserDashboardPanel userDashboard;\n    private ManagerDashboardPanel managerDashboard;\n    private CoordinatorDashboardPanel coordinatorDashboard;\n\n    public static final String LOGIN       = \"LOGIN\";\n    public static final String USER        = \"USER\";\n    public static final String MANAGER     = \"MANAGER\";\n    public static final String COORDINATOR = \"COORDINATOR\";\n\n    public static MainFrame getInstance() {\n        if (instance == null) instance = new MainFrame();\n        return instance;\n    }\n\n    private MainFrame() {\n        super(\"Lab Equipment Reservation System — York University\");\n        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        setSize(1100, 700);\n        setLocationRelativeTo(null);\n\n        cardLayout = new CardLayout();\n        mainPanel  = new JPanel(cardLayout);\n\n        loginPanel           = new LoginPanel(this);\n        userDashboard        = new UserDashboardPanel(this);\n        managerDashboard     = new ManagerDashboardPanel(this);\n        coordinatorDashboard = new CoordinatorDashboardPanel(this);\n\n        mainPanel.add(loginPanel,           LOGIN);\n        mainPanel.add(userDashboard,        USER);\n        mainPanel.add(managerDashboard,     MANAGER);\n        mainPanel.add(coordinatorDashboard, COORDINATOR);\n\n        add(mainPanel);\n        showPanel(LOGIN);\n    }\n\n    public void showPanel(String name) {\n        cardLayout.show(mainPanel, name);\n    }\n\n    public void onLoginSuccess(User user) {\n        String type = user.getUserType().toUpperCase();\n        switch (type) {\n            case \"COORDINATOR\":\n                coordinatorDashboard.setCurrentUser(user);\n                coordinatorDashboard.refresh();\n                showPanel(COORDINATOR);\n                break;\n            case \"MANAGER\":\n                managerDashboard.setCurrentUser(user);\n                managerDashboard.refresh();\n                showPanel(MANAGER);\n                break;\n            default: // STUDENT, FACULTY, RESEARCHER, GUEST\n                userDashboard.setCurrentUser(user);\n                userDashboard.refresh();\n                showPanel(USER);\n                break;\n        }\n    }\n\n    public static void main(String[] args) {\n        SwingUtilities.invokeLater(() -> MainFrame.getInstance().setVisible(true));\n    }\n}\n"
  },
  {
    "path": "D2/src/gui/ManagerDashboardPanel.java",
    "content": "package gui;\n\n// pre determined login\nimport javax.swing.*;\nimport javax.swing.table.*;\nimport java.awt.*;\nimport java.util.List;\nimport data.*;\nimport model.*;\nimport pattern.observer.*;\nimport pattern.state.*;\n\npublic class ManagerDashboardPanel extends JPanel {\n    private static final long serialVersionUID = 1L;\n\n    private MainFrame frame;\n    protected User currentUser;\n\n    protected EquipmentDAO equipDAO = new EquipmentDAO(\"data/equipment.csv\");\n    protected UserDAO userDAO       = new UserDAO(\"data/users.csv\");\n    protected BookingDAO bookDAO    = new BookingDAO(\"data/bookings.csv\");\n\n    protected DefaultTableModel equipModel, pendModel, bookModel;\n    protected JTable equipTable, pendTable, bookTable;\n    private JTextField eqID, eqName, eqDesc, eqType, eqBuilding, eqRoom;\n    protected JLabel status;\n    private JLabel navInfo;\n\n    public ManagerDashboardPanel(MainFrame frame) { this(frame, true); }\n\n    protected ManagerDashboardPanel(MainFrame frame, boolean standalone) {\n        this.frame = frame;\n        if (standalone) build();\n    }\n\n    public void setCurrentUser(User u) { this.currentUser = u; }\n\n    public void refresh() {\n        try { equipDAO.load(); userDAO.load(); bookDAO.load(); } catch (Exception e) { e.printStackTrace(); }\n        if (currentUser != null && navInfo != null)\n            navInfo.setText(\"  Lab Manager  |  \" + currentUser.getName());\n        refreshEquip();\n        refreshPending();\n        refreshAllBookings();\n    }\n\n    protected void build() {\n        setBackground(UI.BG);\n        setLayout(new BorderLayout());\n\n        JButton logout = UI.button(\"Logout\", UI.DANGER);\n        logout.addActionListener(e -> frame.showPanel(MainFrame.LOGIN));\n        navInfo = new JLabel(\"  \");\n        navInfo.setForeground(new Color(148,163,184));\n        navInfo.setFont(new Font(\"SansSerif\", Font.PLAIN, 12));\n        JPanel nav = UI.navBar(\"🔧 Manager Console\", \"\", logout);\n        nav.add(navInfo, BorderLayout.CENTER);\n        add(nav, BorderLayout.NORTH);\n\n        JTabbedPane tabs = buildTabs();\n        add(tabs, BorderLayout.CENTER);\n\n        status = UI.statusBar();\n        add(status, BorderLayout.SOUTH);\n    }\n\n    protected JTabbedPane buildTabs() {\n        JTabbedPane tabs = new JTabbedPane();\n        tabs.setFont(new Font(\"SansSerif\", Font.BOLD, 12));\n        tabs.addTab(\"⚠ Pending Approvals\", buildPendingTab());\n        tabs.addTab(\"🔬 Equipment\", buildEquipTab());\n        tabs.addTab(\"➕ Add Equipment\", buildAddTab());\n        tabs.addTab(\"📋 All Bookings\", buildBookingsTab());\n        return tabs;\n    }\n\n    protected JPanel buildPendingTab() {\n        JPanel p = new JPanel(new BorderLayout(10, 10));\n        p.setBackground(UI.BG);\n        p.setBorder(BorderFactory.createEmptyBorder(14,14,14,14));\n        p.add(UI.heading(\"Pending Account Approvals (Req1)\"), BorderLayout.NORTH);\n\n        pendModel = UI.tableModel(\"User ID\",\"Name\",\"Email\",\"Type\",\"Staff/Cert ID\",\"Department\",\"Status\");\n        pendTable = UI.styledTable(pendModel);\n        pendTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        p.add(new JScrollPane(pendTable), BorderLayout.CENTER);\n\n        JPanel btns = new JPanel(new FlowLayout(FlowLayout.LEFT, 8, 8));\n        btns.setBackground(UI.BG);\n        JButton approve = UI.button(\"✔ Approve\", UI.SUCCESS);\n        JButton reject  = UI.button(\"✘ Reject\",  UI.DANGER);\n        JButton refresh = UI.button(\"↻ Refresh\", UI.YORKU_RED);\n        approve.addActionListener(e -> approve());\n        reject.addActionListener(e -> reject());\n        refresh.addActionListener(e -> refreshPending());\n        btns.add(approve); btns.add(reject); btns.add(refresh);\n        p.add(btns, BorderLayout.SOUTH);\n        return p;\n    }\n\n    protected JPanel buildEquipTab() {\n        JPanel p = new JPanel(new BorderLayout(10, 10));\n        p.setBackground(UI.BG);\n        p.setBorder(BorderFactory.createEmptyBorder(14,14,14,14));\n        p.add(UI.heading(\"Equipment Management (Req6)\"), BorderLayout.NORTH);\n\n        equipModel = UI.tableModel(\"ID\",\"Name\",\"Description\",\"Type\",\"Status\",\"Building\",\"Room\");\n        equipTable = UI.styledTable(equipModel);\n        equipTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        p.add(new JScrollPane(equipTable), BorderLayout.CENTER);\n\n        JPanel btns = new JPanel(new FlowLayout(FlowLayout.LEFT, 8, 8));\n        btns.setBackground(UI.BG);\n        JButton enable  = UI.button(\"✔ Enable\",      UI.SUCCESS);\n        JButton disable = UI.button(\"✘ Disable\",     UI.WARNING);\n        JButton maint   = UI.button(\"🔧 Maintenance\", UI.DANGER);\n        enable.addActionListener(e  -> changeStatus(\"AVAILABLE\"));\n        disable.addActionListener(e -> changeStatus(\"DISABLED\"));\n        maint.addActionListener(e   -> changeStatus(\"MAINTENANCE\"));\n        btns.add(enable); btns.add(disable); btns.add(maint);\n        p.add(btns, BorderLayout.SOUTH);\n        return p;\n    }\n\n    protected JPanel buildAddTab() {\n        JPanel outer = new JPanel(new GridBagLayout());\n        outer.setBackground(UI.BG);\n\n        JPanel form = UI.card(\"Add New Equipment (Req6, Req7)\");\n        eqID       = addField(form, \"Equipment ID (required — Req7)\");\n        eqName     = addField(form, \"Name\");\n        eqDesc     = addField(form, \"Description (required — Req7)\");\n        eqType     = addField(form, \"Type\");\n        eqBuilding = addField(form, \"Building Name (required — Req7)\");\n        eqRoom     = addField(form, \"Room Number (required — Req7)\");\n        form.add(Box.createVerticalStrut(12));\n        JButton add = UI.button(\"Add Equipment\", UI.YORKU_RED);\n        add.setAlignmentX(Component.LEFT_ALIGNMENT);\n        add.addActionListener(e -> addEquipment());\n        form.add(add);\n\n        JPanel wrap = new JPanel(new BorderLayout());\n        wrap.setBackground(UI.CARD);\n        wrap.setBorder(BorderFactory.createLineBorder(UI.BORDER));\n        wrap.add(form, BorderLayout.CENTER);\n        outer.add(wrap);\n        return outer;\n    }\n\n    protected JPanel buildBookingsTab() {\n        JPanel p = new JPanel(new BorderLayout(10, 10));\n        p.setBackground(UI.BG);\n        p.setBorder(BorderFactory.createEmptyBorder(14,14,14,14));\n        p.add(UI.heading(\"All Bookings / Usage Report (Req5, Req8)\"), BorderLayout.NORTH);\n\n        bookModel = UI.tableModel(\"Booking ID\",\"User\",\"Equipment\",\"Start\",\"End\",\"Status\",\"Deposit\",\"Payment\");\n        bookTable = UI.styledTable(bookModel);\n        p.add(new JScrollPane(bookTable), BorderLayout.CENTER);\n\n        JButton refresh = UI.button(\"↻ Refresh\", UI.YORKU_RED);\n        refresh.addActionListener(e -> refreshAllBookings());\n        JPanel btns = new JPanel(new FlowLayout(FlowLayout.LEFT, 8, 8));\n        btns.setBackground(UI.BG);\n        btns.add(refresh);\n        p.add(btns, BorderLayout.SOUTH);\n        return p;\n    }\n\n    protected void refreshEquip() {\n        if (equipModel == null) return;\n        equipModel.setRowCount(0);\n        for (Equipment eq : equipDAO.getAllEquipment())\n            equipModel.addRow(new Object[]{\n                eq.getEquipmentID(), eq.getName(), eq.getDescription(),\n                eq.getType(), eq.getStatus(), eq.getBuildingName(), eq.getRoomNumber()\n            });\n    }\n\n    protected void refreshPending() {\n        if (pendModel == null) return;\n        try { userDAO.load(); } catch (Exception e) { e.printStackTrace(); }\n        pendModel.setRowCount(0);\n        int count = 0;\n        for (User u : userDAO.getAllUsers()) {\n            if (\"PENDING\".equals(u.getStatus())) {\n                pendModel.addRow(new Object[]{\n                    u.getUserID(), u.getName(), u.getEmail(),\n                    u.getUserType(), u.getStaffID(), u.getDepartment(), u.getStatus()\n                });\n                count++;\n            }\n        }\n        if (status != null)\n            UI.setStatus(status, count > 0 ? count + \" pending approval(s)\" : \"No pending approvals\", count > 0);\n    }\n\n    protected void refreshAllBookings() {\n        if (bookModel == null) return;\n        try { bookDAO.load(); } catch (Exception e) { e.printStackTrace(); }\n        bookModel.setRowCount(0);\n        for (Reservation r : bookDAO.getAllBookings())\n            bookModel.addRow(new Object[]{\n                r.getBookingID(), r.getUserID(), r.getEquipmentID(),\n                r.getStartTime(), r.getEndTime(), r.getStatus(),\n                \"$\"+r.getDepositAmount(), r.getPaymentMethod()\n            });\n    }\n\n    private void approve() {\n        int row = pendTable.getSelectedRow();\n        if (row < 0) { UI.setStatus(status, \"Select a user to approve.\", true); return; }\n        String uid = (String) pendModel.getValueAt(row, 0);\n        String name = (String) pendModel.getValueAt(row, 1);\n        User u = userDAO.findByID(uid);\n        if (u == null) return;\n        u.setStatus(\"ACTIVE\");\n        userDAO.updateUser(u);\n        try { userDAO.save(); } catch (Exception e) { e.printStackTrace(); }\n        UI.setStatus(status, \"✔ Approved: \" + name + \". They can now log in.\", false);\n        refreshPending();\n    }\n\n    private void reject() {\n        int row = pendTable.getSelectedRow();\n        if (row < 0) { UI.setStatus(status, \"Select a user to reject.\", true); return; }\n        String uid = (String) pendModel.getValueAt(row, 0);\n        String name = (String) pendModel.getValueAt(row, 1);\n        User u = userDAO.findByID(uid);\n        if (u == null) return;\n        u.setStatus(\"REJECTED\");\n        userDAO.updateUser(u);\n        try { userDAO.save(); } catch (Exception e) { e.printStackTrace(); }\n        UI.setStatus(status, \"✘ Rejected: \" + name, false);\n        refreshPending();\n    }\n\n    protected void changeStatus(String newStatus) {\n        int row = equipTable.getSelectedRow();\n        if (row < 0) { UI.setStatus(status, \"Select equipment.\", true); return; }\n        String eqid = (String) equipModel.getValueAt(row, 0);\n        Equipment eq = equipDAO.findByID(eqid);\n        if (eq == null) return;\n\n        EquipmentContext ctx = new EquipmentContext(eqid, eq.getStatus());\n        List<User> affected = new java.util.ArrayList<>();\n        for (Reservation r : bookDAO.getBookingsByEquipment(eqid))\n            if (\"CONFIRMED\".equals(r.getStatus())) {\n                User u = userDAO.findByID(r.getUserID());\n                if (u != null) affected.add(u);\n            }\n        UserNotificationObserver notifier = new UserNotificationObserver(affected);\n        ctx.registerObserver(notifier);\n\n        switch (newStatus) {\n            case \"AVAILABLE\":   ctx.enable(); break;\n            case \"DISABLED\":    ctx.disable(); break;\n            case \"MAINTENANCE\": ctx.markUnderMaintenance(); break;\n        }\n        eq.setStatus(ctx.getStatusString());\n        equipDAO.updateEquipment(eq);\n        try { equipDAO.save(); } catch (Exception e) { e.printStackTrace(); }\n\n        String log = notifier.getNotificationLog();\n        UI.setStatus(status, eqid + \" → \" + newStatus\n            + (log.isEmpty() ? \"\" : \" | Notified \" + affected.size() + \" user(s)\"), false);\n        refreshEquip();\n    }\n\n    private void addEquipment() {\n        String id = eqID.getText().trim(), name = eqName.getText().trim();\n        String desc = eqDesc.getText().trim(), type = eqType.getText().trim();\n        String bld = eqBuilding.getText().trim(), room = eqRoom.getText().trim();\n        if (id.isEmpty() || name.isEmpty() || desc.isEmpty() || bld.isEmpty() || room.isEmpty()) {\n            UI.setStatus(status, \"ID, Name, Description, Building and Room are required (Req7).\", true); return;\n        }\n        if (equipDAO.findByID(id) != null) { UI.setStatus(status, \"Equipment ID already exists.\", true); return; }\n        equipDAO.addEquipment(new Equipment(id, name, desc, type, \"AVAILABLE\", bld, room));\n        try { equipDAO.save(); } catch (Exception e) { e.printStackTrace(); }\n        UI.setStatus(status, \"Equipment \" + id + \" added.\", false);\n        refreshEquip();\n        eqID.setText(\"\"); eqName.setText(\"\"); eqDesc.setText(\"\"); eqType.setText(\"\"); eqBuilding.setText(\"\"); eqRoom.setText(\"\");\n    }\n\n    protected JTextField addField(JPanel form, String labelText) {\n        form.add(UI.label(labelText));\n        form.add(Box.createVerticalStrut(2));\n        JTextField f = UI.field(\"\");\n        f.setMaximumSize(new Dimension(380, 34));\n        form.add(f);\n        form.add(Box.createVerticalStrut(10));\n        return f;\n    }\n}\n"
  },
  {
    "path": "D2/src/gui/UI.java",
    "content": "package gui;\n\nimport javax.swing.*;\nimport javax.swing.border.*;\nimport javax.swing.table.*;\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class UI {\n    public static final Color YORKU_RED   = new Color(0xe3, 0x18, 0x37);\n    public static final Color YORKU_DARK  = new Color(0xb8, 0x10, 0x2a);\n    public static final Color BG          = new Color(0xf5, 0xf6, 0xf8);\n    public static final Color CARD        = Color.WHITE;\n    public static final Color NAV_BG      = new Color(0x1a, 0x1a, 0x2e);\n    public static final Color NAV_FG      = new Color(0xe8, 0xe8, 0xf0);\n    public static final Color HEADER_BG   = new Color(0xf8, 0xf9, 0xfa);\n    public static final Color BORDER      = new Color(0xd8, 0xda, 0xde);\n    public static final Color ROW_ALT     = new Color(0xfa, 0xfb, 0xfc);\n    public static final Color ROW_SEL_BG  = new Color(0xfb, 0xe9, 0xec);\n    public static final Color ROW_SEL_FG  = new Color(0x8c, 0x0b, 0x1e);\n    public static final Color TEXT        = new Color(0x1a, 0x1a, 0x2e);\n    public static final Color TEXT_MUTED  = new Color(0x6c, 0x75, 0x7d);\n    public static final Color SUCCESS     = new Color(0x19, 0x87, 0x54);\n    public static final Color DANGER      = new Color(0xdc, 0x35, 0x45);\n    public static final Color WARNING     = new Color(0xd9, 0x73, 0x06);\n    public static final Color INFO        = new Color(0x0d, 0x6e, 0xfd);\n    public static final Color SECONDARY   = new Color(0x6c, 0x75, 0x7d);\n\n    public static final Font F_TITLE  = new Font(\"Segoe UI\", Font.BOLD, 22);\n    public static final Font F_HEAD   = new Font(\"Segoe UI\", Font.BOLD, 16);\n    public static final Font F_SUB    = new Font(\"Segoe UI\", Font.BOLD, 13);\n    public static final Font F_BODY   = new Font(\"Segoe UI\", Font.PLAIN, 13);\n    public static final Font F_SMALL  = new Font(\"Segoe UI\", Font.PLAIN, 11);\n    public static final Font F_LABEL  = new Font(\"Segoe UI\", Font.BOLD, 11);\n\n    public static JButton button(String text, Color bg) {\n        Color hover = bg.darker();\n        JButton b = new JButton(text);\n        b.setFont(F_SUB); b.setForeground(Color.WHITE); b.setBackground(bg);\n        b.setOpaque(true); b.setBorderPainted(false); b.setFocusPainted(false);\n        b.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n        b.setBorder(BorderFactory.createEmptyBorder(8, 16, 8, 16));\n        b.addMouseListener(new MouseAdapter() {\n            public void mouseEntered(MouseEvent e) { b.setBackground(hover); }\n            public void mouseExited(MouseEvent e)  { b.setBackground(bg); }\n        });\n        return b;\n    }\n\n    public static JButton primary(String t)   { return button(t, YORKU_RED); }\n    public static JButton secondary(String t) { return button(t, SECONDARY); }\n    public static JButton success(String t)   { return button(t, SUCCESS); }\n    public static JButton danger(String t)    { return button(t, DANGER); }\n    public static JButton warning(String t)   { return button(t, WARNING); }\n    public static JButton info(String t)      { return button(t, INFO); }\n\n    public static JTextField field(String placeholder) {\n        JTextField f = new JTextField(placeholder);\n        styleInput(f); return f;\n    }\n    public static JPasswordField password() {\n        JPasswordField f = new JPasswordField();\n        styleInput(f); return f;\n    }\n    public static JComboBox<String> combo(String... items) {\n        JComboBox<String> c = new JComboBox<>(items);\n        c.setFont(F_BODY); c.setBackground(CARD);\n        c.setBorder(inputBorder());\n        c.setMaximumSize(new Dimension(Integer.MAX_VALUE, 36));\n        c.setAlignmentX(Component.LEFT_ALIGNMENT);\n        return c;\n    }\n    private static void styleInput(JTextField f) {\n        f.setFont(F_BODY); f.setBackground(CARD);\n        f.setMaximumSize(new Dimension(Integer.MAX_VALUE, 36));\n        f.setAlignmentX(Component.LEFT_ALIGNMENT);\n        f.setBorder(inputBorder());\n        f.addFocusListener(new FocusAdapter() {\n            public void focusGained(FocusEvent e) {\n                f.setBorder(BorderFactory.createCompoundBorder(\n                    new LineBorder(YORKU_RED, 2, true),\n                    BorderFactory.createEmptyBorder(5, 9, 5, 9)));\n            }\n            public void focusLost(FocusEvent e) { f.setBorder(inputBorder()); }\n        });\n    }\n    private static Border inputBorder() {\n        return BorderFactory.createCompoundBorder(\n            new LineBorder(BORDER, 1, true),\n            BorderFactory.createEmptyBorder(6, 10, 6, 10));\n    }\n\n    public static JLabel heading(String t) {\n        JLabel l = new JLabel(t); l.setFont(F_HEAD); l.setForeground(TEXT); return l;\n    }\n    public static JLabel label(String t) {\n        JLabel l = new JLabel(t); l.setFont(F_LABEL); l.setForeground(TEXT_MUTED);\n        l.setAlignmentX(Component.LEFT_ALIGNMENT);\n        l.setBorder(BorderFactory.createEmptyBorder(0,0,2,0)); return l;\n    }\n\n    public static JPanel navBar(String appTitle, String userInfo, JButton... actions) {\n        JPanel bar = new JPanel(new BorderLayout());\n        bar.setBackground(NAV_BG);\n        bar.setBorder(BorderFactory.createMatteBorder(0, 0, 3, 0, YORKU_RED));\n        JPanel left = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));\n        left.setBackground(NAV_BG);\n        JLabel badge = new JLabel(\"  Y  \");\n        badge.setFont(new Font(\"Segoe UI\", Font.BOLD, 14));\n        badge.setForeground(Color.WHITE); badge.setBackground(YORKU_RED); badge.setOpaque(true);\n        badge.setBorder(BorderFactory.createEmptyBorder(10,12,10,12));\n        left.add(badge);\n        JLabel title = new JLabel(\"  \" + appTitle);\n        title.setFont(F_HEAD); title.setForeground(NAV_FG);\n        left.add(title);\n        JLabel info = new JLabel(userInfo);\n        info.setFont(F_SMALL); info.setForeground(new Color(0xa0,0xa8,0xb8));\n        info.setHorizontalAlignment(SwingConstants.CENTER);\n        JPanel right = new JPanel(new FlowLayout(FlowLayout.RIGHT, 8, 8));\n        right.setBackground(NAV_BG);\n        for (JButton a : actions) right.add(a);\n        bar.add(left, BorderLayout.WEST);\n        bar.add(info, BorderLayout.CENTER);\n        bar.add(right, BorderLayout.EAST);\n        return bar;\n    }\n\n    public static JPanel card(String title) {\n        JPanel p = new JPanel();\n        p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));\n        p.setBackground(CARD);\n        if (title != null) {\n            JLabel h = new JLabel(title); h.setFont(F_HEAD); h.setForeground(TEXT);\n            h.setAlignmentX(Component.LEFT_ALIGNMENT);\n            h.setBorder(BorderFactory.createEmptyBorder(0,0,10,0));\n            p.add(h);\n            JSeparator sep = new JSeparator();\n            sep.setForeground(new Color(0xe3,0x18,0x37,60));\n            sep.setMaximumSize(new Dimension(Integer.MAX_VALUE, 2));\n            p.add(sep); p.add(Box.createVerticalStrut(14));\n        }\n        return p;\n    }\n\n    public static JLabel statusBar() {\n        JLabel l = new JLabel(\"  Ready\"); l.setFont(F_SMALL); l.setForeground(TEXT_MUTED);\n        l.setBackground(HEADER_BG); l.setOpaque(true);\n        l.setBorder(BorderFactory.createMatteBorder(1,0,0,0,BORDER));\n        l.setPreferredSize(new Dimension(0, 28)); return l;\n    }\n    public static void setStatus(JLabel bar, String msg, boolean error) {\n        bar.setText(\"  \" + msg);\n        bar.setForeground(error ? DANGER : SUCCESS);\n    }\n\n    public static DefaultTableModel tableModel(String... cols) {\n        return new DefaultTableModel(cols, 0) {\n            public boolean isCellEditable(int r, int c) { return false; }\n        };\n    }\n    public static JTable styledTable(DefaultTableModel model) {\n        JTable t = new JTable(model) {\n            public Component prepareRenderer(TableCellRenderer r, int row, int col) {\n                Component c = super.prepareRenderer(r, row, col);\n                if (isRowSelected(row)) { c.setBackground(ROW_SEL_BG); c.setForeground(ROW_SEL_FG); }\n                else { c.setBackground(row%2==0?CARD:ROW_ALT); c.setForeground(TEXT); }\n                return c;\n            }\n        };\n        t.setFont(F_BODY); t.setRowHeight(30); t.setShowVerticalLines(false);\n        t.setShowHorizontalLines(true); t.setGridColor(new Color(0xee,0xee,0xf2));\n        t.setIntercellSpacing(new Dimension(0,0));\n        t.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        t.setFillsViewportHeight(true);\n        JTableHeader hdr = t.getTableHeader();\n        hdr.setFont(F_SUB); hdr.setForeground(TEXT_MUTED); hdr.setBackground(HEADER_BG);\n        hdr.setBorder(BorderFactory.createMatteBorder(0,0,2,0,BORDER));\n        hdr.setReorderingAllowed(false);\n        hdr.setPreferredSize(new Dimension(hdr.getPreferredSize().width, 36));\n        return t;\n    }\n    public static JScrollPane scroll(JTable t) {\n        JScrollPane sp = new JScrollPane(t);\n        sp.setBorder(BorderFactory.createLineBorder(BORDER));\n        sp.getViewport().setBackground(CARD); return sp;\n    }\n    public static JTabbedPane tabs() {\n        JTabbedPane tp = new JTabbedPane();\n        tp.setFont(F_SUB); tp.setBackground(BG); tp.setBorder(null); return tp;\n    }\n    public static JTextField formField(JPanel form, String lbl) {\n        form.add(label(lbl)); form.add(Box.createVerticalStrut(3));\n        JTextField f = field(\"\"); f.setMaximumSize(new Dimension(400,36)); form.add(f);\n        form.add(Box.createVerticalStrut(12)); return f;\n    }\n    public static JPasswordField formPassword(JPanel form, String lbl) {\n        form.add(label(lbl)); form.add(Box.createVerticalStrut(3));\n        JPasswordField f = password(); f.setMaximumSize(new Dimension(400,36)); form.add(f);\n        form.add(Box.createVerticalStrut(12)); return f;\n    }\n    public static JComboBox<String> formCombo(JPanel form, String lbl, String... items) {\n        form.add(label(lbl)); form.add(Box.createVerticalStrut(3));\n        JComboBox<String> c = combo(items); c.setMaximumSize(new Dimension(400,36)); form.add(c);\n        form.add(Box.createVerticalStrut(12)); return c;\n    }\n    public static JPanel tabContent() {\n        JPanel p = new JPanel(new BorderLayout(0,10));\n        p.setBackground(BG); p.setBorder(BorderFactory.createEmptyBorder(14,14,14,14)); return p;\n    }\n    public static JPanel buttonRow(JButton... buttons) {\n        JPanel row = new JPanel(new FlowLayout(FlowLayout.LEFT, 8, 0));\n        row.setBackground(BG); row.setBorder(BorderFactory.createEmptyBorder(0,0,10,0));\n        for (JButton b : buttons) row.add(b); return row;\n    }\n}\n"
  },
  {
    "path": "D2/src/gui/UserDashboardPanel.java",
    "content": "package gui;\n\nimport javax.swing.*;\nimport javax.swing.table.*;\nimport java.awt.*;\nimport data.*;\nimport model.*;\nimport pattern.command.*;\nimport pattern.singleton.BookingSystem;\nimport pattern.strategy.*;\n\npublic class UserDashboardPanel extends JPanel {\n    private static final long serialVersionUID = 1L;\n\n    private MainFrame frame;\n    private User currentUser;\n\n    private EquipmentDAO equipDAO = new EquipmentDAO(\"data/equipment.csv\");\n    private BookingDAO bookDAO    = new BookingDAO(\"data/bookings.csv\");\n    private ReservationService svc = new ReservationService();\n\n    private DefaultTableModel equipModel, bookModel;\n    private JTable equipTable, bookTable;\n    private JTextField startField, endField, extendField;\n    private JComboBox<String> payCombo;\n    private JLabel status, userInfo;\n\n    public UserDashboardPanel(MainFrame frame) {\n        this.frame = frame;\n        build();\n    }\n\n    public void setCurrentUser(User u) { this.currentUser = u; }\n\n    public void refresh() {\n        try { equipDAO.load(); bookDAO.load(); } catch (Exception e) { e.printStackTrace(); }\n        if (currentUser != null)\n            userInfo.setText(\"  \" + currentUser.getUserType() + \"  |  \" + currentUser.getName()\n                + \"  |  Fee: $\" + currentUser.getFeeRate() + \"/hr  |  ID: \" + currentUser.getStaffID());\n        refreshEquip();\n        refreshBookings();\n    }\n\n    private void build() {\n        setBackground(UI.BG);\n        setLayout(new BorderLayout());\n\n        // Nav\n        JButton logout = UI.button(\"Logout\", UI.DANGER);\n        logout.addActionListener(e -> frame.showPanel(MainFrame.LOGIN));\n        userInfo = new JLabel(\"  \");\n        userInfo.setFont(new Font(\"SansSerif\", Font.PLAIN, 12));\n        userInfo.setForeground(new Color(148, 163, 184));\n        JPanel nav = UI.navBar(\"🔬 Lab Equipment Reservation\", \"\", logout);\n        nav.add(userInfo, BorderLayout.CENTER);\n        add(nav, BorderLayout.NORTH);\n\n        // Content\n        JTabbedPane tabs = new JTabbedPane();\n        tabs.setFont(new Font(\"SansSerif\", Font.BOLD, 12));\n        tabs.setBackground(UI.BG);\n        tabs.addTab(\"Browse & Reserve Equipment\", buildBrowseTab());\n        tabs.addTab(\"My Bookings\", buildBookingsTab());\n        add(tabs, BorderLayout.CENTER);\n\n        // Status\n        status = UI.statusBar();\n        add(status, BorderLayout.SOUTH);\n    }\n\n    private JPanel buildBrowseTab() {\n        JPanel p = new JPanel(new BorderLayout(10, 10));\n        p.setBackground(UI.BG);\n        p.setBorder(BorderFactory.createEmptyBorder(14, 14, 14, 14));\n\n        // Equipment table\n        equipModel = UI.tableModel(\"ID\", \"Name\", \"Description\", \"Type\", \"Status\", \"Location\");\n        equipTable = UI.styledTable(equipModel);\n        equipTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        JScrollPane scroll = new JScrollPane(equipTable);\n        scroll.setBorder(BorderFactory.createTitledBorder(\n            BorderFactory.createLineBorder(UI.BORDER), \"Available Equipment (Req3)\"));\n        p.add(scroll, BorderLayout.CENTER);\n\n        // Booking form\n        JPanel form = new JPanel(new GridBagLayout());\n        form.setBackground(UI.CARD);\n        form.setBorder(BorderFactory.createCompoundBorder(\n            BorderFactory.createTitledBorder(BorderFactory.createLineBorder(UI.BORDER),\n                \"Make a Reservation (Req3, Req4, Req10)\"),\n            BorderFactory.createEmptyBorder(10, 12, 10, 12)\n        ));\n\n        GridBagConstraints gc = new GridBagConstraints();\n        gc.insets = new Insets(4, 6, 4, 6);\n        gc.fill = GridBagConstraints.HORIZONTAL;\n\n        gc.gridx=0; gc.gridy=0; form.add(new JLabel(\"Start (yyyy-MM-dd HH:mm):\"), gc);\n        gc.gridx=1; startField = UI.field(\"2026-04-10 09:00\"); form.add(startField, gc);\n\n        gc.gridx=2; form.add(new JLabel(\"End (yyyy-MM-dd HH:mm):\"), gc);\n        gc.gridx=3; endField = UI.field(\"2026-04-10 11:00\"); form.add(endField, gc);\n\n        gc.gridx=4; form.add(new JLabel(\"Payment Method (Req10):\"), gc);\n        gc.gridx=5; payCombo = new JComboBox<>(new String[]{\"CREDIT\",\"DEBIT\",\"INSTITUTIONAL\",\"GRANT\"});\n        payCombo.setFont(new Font(\"SansSerif\", Font.PLAIN, 12));\n        form.add(payCombo, gc);\n\n        gc.gridx=6;\n        JButton resBtn = UI.button(\"Reserve Selected\", UI.YORKU_RED);\n        resBtn.addActionListener(e -> reserve());\n        form.add(resBtn, gc);\n\n        p.add(form, BorderLayout.SOUTH);\n        return p;\n    }\n\n    private JPanel buildBookingsTab() {\n        JPanel p = new JPanel(new BorderLayout(10, 10));\n        p.setBackground(UI.BG);\n        p.setBorder(BorderFactory.createEmptyBorder(14, 14, 14, 14));\n\n        bookModel = UI.tableModel(\"Booking ID\",\"Equipment\",\"Start\",\"End\",\"Status\",\"Deposit\",\"Payment\",\"Extended\");\n        bookTable = UI.styledTable(bookModel);\n        bookTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        JScrollPane scroll = new JScrollPane(bookTable);\n        scroll.setBorder(BorderFactory.createTitledBorder(\n            BorderFactory.createLineBorder(UI.BORDER), \"My Bookings\"));\n        p.add(scroll, BorderLayout.CENTER);\n\n        // Action buttons\n        JPanel actions = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 8));\n        actions.setBackground(UI.CARD);\n        actions.setBorder(BorderFactory.createTitledBorder(\n            BorderFactory.createLineBorder(UI.BORDER), \"Booking Actions (Req8, Req9, Req4)\"));\n\n        JButton cancelBtn = UI.button(\"Cancel Booking (Req8)\", UI.DANGER);\n        cancelBtn.addActionListener(e -> cancelBooking());\n        actions.add(cancelBtn);\n\n        actions.add(new JLabel(\"  Extend to (yyyy-MM-dd HH:mm):\"));\n        extendField = UI.field(\"2026-04-10 13:00\");\n        extendField.setPreferredSize(new Dimension(160, 32));\n        actions.add(extendField);\n\n        JButton extBtn = UI.button(\"Extend Reservation (Req9)\", UI.YORKU_RED);\n        extBtn.addActionListener(e -> extend());\n        actions.add(extBtn);\n\n        JButton forfeitBtn = UI.button(\"Simulate No-Show / Forfeit Deposit (Req4)\", UI.WARNING);\n        forfeitBtn.addActionListener(e -> forfeit());\n        actions.add(forfeitBtn);\n\n        p.add(actions, BorderLayout.SOUTH);\n        return p;\n    }\n\n    private void refreshEquip() {\n        equipModel.setRowCount(0);\n        for (Equipment eq : equipDAO.getAllEquipment())\n            equipModel.addRow(new Object[]{\n                eq.getEquipmentID(), eq.getName(), eq.getDescription(),\n                eq.getType(), eq.getStatus(),\n                eq.getBuildingName() + \" Rm \" + eq.getRoomNumber()\n            });\n    }\n\n    private void refreshBookings() {\n        bookModel.setRowCount(0);\n        if (currentUser == null) return;\n        for (Reservation r : bookDAO.getBookingsByUser(currentUser.getUserID()))\n            bookModel.addRow(new Object[]{\n                r.getBookingID(), r.getEquipmentID(),\n                r.getStartTime(), r.getEndTime(), r.getStatus(),\n                \"$\" + r.getDepositAmount(), r.getPaymentMethod(),\n                r.isExtended() ? \"Yes\" : \"No\"\n            });\n    }\n\n    private void reserve() {\n        int row = equipTable.getSelectedRow();\n        if (row < 0) { UI.setStatus(status, \"Select equipment first.\", true); return; }\n        String eqID   = (String) equipModel.getValueAt(row, 0);\n        String eqStat = (String) equipModel.getValueAt(row, 4);\n        if (!\"AVAILABLE\".equals(eqStat)) { UI.setStatus(status, \"Equipment is not available.\", true); return; }\n\n        String start = startField.getText().trim();\n        String end   = endField.getText().trim();\n        String pay   = (String) payCombo.getSelectedItem();\n        if (start.isEmpty() || end.isEmpty()) { UI.setStatus(status, \"Enter start and end times.\", true); return; }\n\n        double deposit = currentUser.getFeeRate();\n        PaymentStrategy strategy = payStrategy(pay);\n        String bkID = \"B\" + System.currentTimeMillis();\n        PaymentTransaction txn = new PaymentTransaction(\"T\" + System.currentTimeMillis(), bkID, deposit, pay);\n        if (!new PaymentProcessor(strategy).processPayment(txn)) {\n            UI.setStatus(status, \"Payment failed.\", true); return;\n        }\n\n        Reservation r = new Reservation(bkID, currentUser.getUserID(), eqID, start, end, pay, deposit);\n        new ReserveCommand(svc, r).execute();\n        bookDAO.addBooking(r);\n        BookingSystem.getInstance().addBooking(r);\n        try { bookDAO.save(); } catch (Exception e) { e.printStackTrace(); }\n\n        UI.setStatus(status, \"✔ Reserved \" + eqID + \" | Booking: \" + bkID + \" | Deposit: $\" + deposit + \" via \" + pay, false);\n        refreshBookings();\n    }\n\n    private void cancelBooking() {\n        int row = bookTable.getSelectedRow();\n        if (row < 0) { UI.setStatus(status, \"Select a booking to cancel.\", true); return; }\n        String bkID = (String) bookModel.getValueAt(row, 0);\n        Reservation r = bookDAO.findByID(bkID);\n        if (r == null) return;\n        new CancelCommand(svc, r).execute();\n        bookDAO.updateBooking(r);\n        try { bookDAO.save(); } catch (Exception e) { e.printStackTrace(); }\n        UI.setStatus(status, \"Booking \" + bkID + \" cancelled.\", false);\n        refreshBookings();\n    }\n\n    private void extend() {\n        int row = bookTable.getSelectedRow();\n        if (row < 0) { UI.setStatus(status, \"Select a booking to extend.\", true); return; }\n        String bkID = (String) bookModel.getValueAt(row, 0);\n        Reservation r = bookDAO.findByID(bkID);\n        if (r == null || !\"CONFIRMED\".equals(r.getStatus())) {\n            UI.setStatus(status, \"Cannot extend this booking.\", true); return;\n        }\n        String newEnd = extendField.getText().trim();\n        if (newEnd.isEmpty()) { UI.setStatus(status, \"Enter new end time.\", true); return; }\n        new ExtendCommand(svc, r, newEnd).execute();\n        bookDAO.updateBooking(r);\n        try { bookDAO.save(); } catch (Exception e) { e.printStackTrace(); }\n        UI.setStatus(status, \"Booking extended to \" + newEnd, false);\n        refreshBookings();\n    }\n\n    private void forfeit() {\n        int row = bookTable.getSelectedRow();\n        if (row < 0) { UI.setStatus(status, \"Select a booking.\", true); return; }\n        String bkID = (String) bookModel.getValueAt(row, 0);\n        Reservation r = bookDAO.findByID(bkID);\n        if (r == null) return;\n        new ForfeitDepositCommand(svc, r).execute();\n        bookDAO.updateBooking(r);\n        try { bookDAO.save(); } catch (Exception e) { e.printStackTrace(); }\n        UI.setStatus(status, \"Deposit forfeited. Amount lost: $\" + r.getDepositAmount(), false);\n        refreshBookings();\n    }\n\n    private PaymentStrategy payStrategy(String m) {\n        switch(m) {\n            case \"DEBIT\":         return new DebitPayment();\n            case \"INSTITUTIONAL\": return new InstitutionalPayment();\n            case \"GRANT\":         return new GrantPayment();\n            default:              return new CreditCardPayment();\n        }\n    }\n}\n"
  },
  {
    "path": "D2/src/model/.gitkeep",
    "content": ""
  },
  {
    "path": "D2/src/model/Deposit.java",
    "content": "package model;\n\npublic class Deposit {\n    private double amount;\n    private boolean isForfeited;\n    private boolean deductedFromTotal;\n\n    public Deposit() {}\n\n    public Deposit(double amount) {\n        this.amount = amount;\n        this.isForfeited = false;\n        this.deductedFromTotal = false;\n    }\n\n    // Called when user is >20 min late (Req4)\n    public void forfeit() {\n        this.isForfeited = true;\n    }\n\n    public double getAmount() { return amount; }\n    public void setAmount(double amount) { this.amount = amount; }\n\n    public boolean isForfeited() { return isForfeited; }\n    public void setForfeited(boolean forfeited) { isForfeited = forfeited; }\n\n    public boolean isDeductedFromTotal() { return deductedFromTotal; }\n    public void setDeductedFromTotal(boolean deductedFromTotal) {\n        this.deductedFromTotal = deductedFromTotal;\n    }\n}\n"
  },
  {
    "path": "D2/src/model/Equipment.java",
    "content": "package model;\n\npublic class Equipment {\n    private String equipmentID;\n    private String name;\n    private String description;\n    private String type;\n    private String status;        // AVAILABLE, DISABLED, MAINTENANCE\n    private String buildingName;\n    private String roomNumber;\n\n    public Equipment() {}\n\n    public Equipment(String equipmentID, String name, String description,\n                     String type, String status, String buildingName, String roomNumber) {\n        this.equipmentID = equipmentID;\n        this.name = name;\n        this.description = description;\n        this.type = type;\n        this.status = status;\n        this.buildingName = buildingName;\n        this.roomNumber = roomNumber;\n    }\n\n    public LabLocation getLabLocation() {\n        return new LabLocation(buildingName, roomNumber);\n    }\n\n    public boolean isAvailable() {\n        return \"AVAILABLE\".equals(status);\n    }\n\n    // Getters and Setters\n    public String getEquipmentID() { return equipmentID; }\n    public void setEquipmentID(String equipmentID) { this.equipmentID = equipmentID; }\n\n    public String getName() { return name; }\n    public void setName(String name) { this.name = name; }\n\n    public String getDescription() { return description; }\n    public void setDescription(String description) { this.description = description; }\n\n    public String getType() { return type; }\n    public void setType(String type) { this.type = type; }\n\n    public String getStatus() { return status; }\n    public void setStatus(String status) { this.status = status; }\n\n    public String getBuildingName() { return buildingName; }\n    public void setBuildingName(String buildingName) { this.buildingName = buildingName; }\n\n    public String getRoomNumber() { return roomNumber; }\n    public void setRoomNumber(String roomNumber) { this.roomNumber = roomNumber; }\n\n    @Override\n    public String toString() {\n        return equipmentID + \" - \" + name + \" [\" + status + \"] @ \" + buildingName + \" \" + roomNumber;\n    }\n}\n"
  },
  {
    "path": "D2/src/model/Faculty.java",
    "content": "package model;\n\npublic class Faculty extends User {\n    private static final double HOURLY_FEE = 15.0;\n\n    public Faculty() {}\n\n    public Faculty(String userID, String name, String email, String password,\n                   String staffID, String status, String department) {\n        super(userID, name, email, password, \"FACULTY\", staffID, status, department);\n    }\n\n    @Override\n    public double getFeeRate() {\n        return HOURLY_FEE;\n    }\n}\n"
  },
  {
    "path": "D2/src/model/Guest.java",
    "content": "package model;\n\npublic class Guest extends User {\n    private static final double HOURLY_FEE = 30.0;\n    private String certificationNumber;\n\n    public Guest() {}\n\n    public Guest(String userID, String name, String email, String password,\n                 String certificationNumber, String status, String department) {\n        super(userID, name, email, password, \"GUEST\", certificationNumber, status, department);\n        this.certificationNumber = certificationNumber;\n    }\n\n    @Override\n    public double getFeeRate() {\n        return HOURLY_FEE;\n    }\n\n    public String getCertificationNumber() { return certificationNumber; }\n    public void setCertificationNumber(String certificationNumber) {\n        this.certificationNumber = certificationNumber;\n    }\n}\n"
  },
  {
    "path": "D2/src/model/HeadLabCoordinator.java",
    "content": "package model;\n\npublic class HeadLabCoordinator extends User {\n    private static final double HOURLY_FEE = 0.0;\n\n    public HeadLabCoordinator() {}\n\n    public HeadLabCoordinator(String userID, String name, String email,\n                               String password, String department) {\n        super(userID, name, email, password, \"COORDINATOR\", \"COORD-001\", \"ACTIVE\", department);\n    }\n\n    @Override\n    public double getFeeRate() { return HOURLY_FEE; }\n\n    // Req2 - only coordinator can create manager accounts\n    public LabManager generateManagerAccount(String managerID, String name,\n                                              String email, String tempPassword, String department) {\n        return new LabManager(managerID, name, email, tempPassword, managerID, department);\n    }\n}\n"
  },
  {
    "path": "D2/src/model/LabLocation.java",
    "content": "package model;\n\npublic class LabLocation {\n    private String buildingName;\n    private String roomNumber;\n\n    public LabLocation() {}\n\n    public LabLocation(String buildingName, String roomNumber) {\n        this.buildingName = buildingName;\n        this.roomNumber = roomNumber;\n    }\n\n    public String getLocationDetails() {\n        return buildingName + \" - Room \" + roomNumber;\n    }\n\n    public String getBuildingName() { return buildingName; }\n    public void setBuildingName(String buildingName) { this.buildingName = buildingName; }\n\n    public String getRoomNumber() { return roomNumber; }\n    public void setRoomNumber(String roomNumber) { this.roomNumber = roomNumber; }\n\n    @Override\n    public String toString() {\n        return buildingName + \",\" + roomNumber;\n    }\n}\n"
  },
  {
    "path": "D2/src/model/LabManager.java",
    "content": "package model;\n\npublic class LabManager extends User {\n    private static final double HOURLY_FEE = 0.0;\n    private String managerID;\n\n    public LabManager() {}\n\n    public LabManager(String userID, String name, String email, String password,\n                      String managerID, String department) {\n        super(userID, name, email, password, \"MANAGER\", managerID, \"ACTIVE\", department);\n        this.managerID = managerID;\n    }\n\n    @Override\n    public double getFeeRate() { return HOURLY_FEE; }\n\n    public String getManagerID() { return managerID; }\n    public void setManagerID(String managerID) { this.managerID = managerID; }\n}\n"
  },
  {
    "path": "D2/src/model/PaymentTransaction.java",
    "content": "package model;\n\npublic class PaymentTransaction {\n    private String transactionID;\n    private String bookingID;\n    private double totalAmount;\n    private String paymentStatus;  // SUCCESS, DECLINED\n    private String paymentMethod;\n\n    public PaymentTransaction() {}\n\n    public PaymentTransaction(String transactionID, String bookingID,\n                               double totalAmount, String paymentMethod) {\n        this.transactionID = transactionID;\n        this.bookingID = bookingID;\n        this.totalAmount = totalAmount;\n        this.paymentMethod = paymentMethod;\n        this.paymentStatus = \"SUCCESS\";\n    }\n\n    // Getters and Setters\n    public String getTransactionID() { return transactionID; }\n    public void setTransactionID(String transactionID) { this.transactionID = transactionID; }\n\n    public String getBookingID() { return bookingID; }\n    public void setBookingID(String bookingID) { this.bookingID = bookingID; }\n\n    public double getTotalAmount() { return totalAmount; }\n    public void setTotalAmount(double totalAmount) { this.totalAmount = totalAmount; }\n\n    public String getPaymentStatus() { return paymentStatus; }\n    public void setPaymentStatus(String paymentStatus) { this.paymentStatus = paymentStatus; }\n\n    public String getPaymentMethod() { return paymentMethod; }\n    public void setPaymentMethod(String paymentMethod) { this.paymentMethod = paymentMethod; }\n}\n"
  },
  {
    "path": "D2/src/model/Researcher.java",
    "content": "package model;\n\npublic class Researcher extends User {\n    private static final double HOURLY_FEE = 20.0;\n\n    public Researcher() {}\n\n    public Researcher(String userID, String name, String email, String password,\n                      String staffID, String status, String department) {\n        super(userID, name, email, password, \"RESEARCHER\", staffID, status, department);\n    }\n\n    @Override\n    public double getFeeRate() {\n        return HOURLY_FEE;\n    }\n}\n"
  },
  {
    "path": "D2/src/model/Reservation.java",
    "content": "package model;\n\npublic class Reservation {\n    private String bookingID;\n    private String userID;\n    private String equipmentID;\n    private String startTime;   // stored as string \"yyyy-MM-dd HH:mm\"\n    private String endTime;\n    private boolean isExtended;\n    private String status;      // CONFIRMED, CANCELLED, FORFEITED\n    private double depositAmount;\n    private boolean depositForfeited;\n    private String paymentMethod; // CREDIT, DEBIT, INSTITUTIONAL, GRANT\n\n    public Reservation() {}\n\n    public Reservation(String bookingID, String userID, String equipmentID,\n                       String startTime, String endTime, String paymentMethod, double depositAmount) {\n        this.bookingID = bookingID;\n        this.userID = userID;\n        this.equipmentID = equipmentID;\n        this.startTime = startTime;\n        this.endTime = endTime;\n        this.isExtended = false;\n        this.status = \"CONFIRMED\";\n        this.depositAmount = depositAmount;\n        this.depositForfeited = false;\n        this.paymentMethod = paymentMethod;\n    }\n\n    public void cancel() { this.status = \"CANCELLED\"; }\n    public void forfeitDeposit() { this.depositForfeited = true; this.status = \"FORFEITED\"; }\n    public void extend(String newEndTime) { this.endTime = newEndTime; this.isExtended = true; }\n\n    // Getters and Setters\n    public String getBookingID() { return bookingID; }\n    public void setBookingID(String bookingID) { this.bookingID = bookingID; }\n\n    public String getUserID() { return userID; }\n    public void setUserID(String userID) { this.userID = userID; }\n\n    public String getEquipmentID() { return equipmentID; }\n    public void setEquipmentID(String equipmentID) { this.equipmentID = equipmentID; }\n\n    public String getStartTime() { return startTime; }\n    public void setStartTime(String startTime) { this.startTime = startTime; }\n\n    public String getEndTime() { return endTime; }\n    public void setEndTime(String endTime) { this.endTime = endTime; }\n\n    public boolean isExtended() { return isExtended; }\n    public void setExtended(boolean extended) { isExtended = extended; }\n\n    public String getStatus() { return status; }\n    public void setStatus(String status) { this.status = status; }\n\n    public double getDepositAmount() { return depositAmount; }\n    public void setDepositAmount(double depositAmount) { this.depositAmount = depositAmount; }\n\n    public boolean isDepositForfeited() { return depositForfeited; }\n    public void setDepositForfeited(boolean depositForfeited) { this.depositForfeited = depositForfeited; }\n\n    public String getPaymentMethod() { return paymentMethod; }\n    public void setPaymentMethod(String paymentMethod) { this.paymentMethod = paymentMethod; }\n\n    @Override\n    public String toString() {\n        return \"Booking [\" + bookingID + \"] \" + equipmentID + \" | \" + startTime + \" to \" + endTime + \" | \" + status;\n    }\n}\n"
  },
  {
    "path": "D2/src/model/Student.java",
    "content": "package model;\n\npublic class Student extends User {\n    private static final double HOURLY_FEE = 10.0;\n\n    public Student() {}\n\n    public Student(String userID, String name, String email, String password,\n                   String staffID, String status, String department) {\n        super(userID, name, email, password, \"STUDENT\", staffID, status, department);\n    }\n\n    @Override\n    public double getFeeRate() {\n        return HOURLY_FEE;\n    }\n}\n"
  },
  {
    "path": "D2/src/model/User.java",
    "content": "package model;\n\npublic abstract class User {\n    protected String userID;\n    protected String name;\n    protected String email;\n    protected String password;\n    protected String userType;   // STUDENT, FACULTY, RESEARCHER, GUEST\n    protected String staffID;    // student/staff ID or certification number (Req8)\n    protected String status;     // ACTIVE, PENDING\n    protected String department;\n\n    public User() {}\n\n    public User(String userID, String name, String email, String password,\n                String userType, String staffID, String status, String department) {\n        this.userID = userID;\n        this.name = name;\n        this.email = email;\n        this.password = password;\n        this.userType = userType;\n        this.staffID = staffID;\n        this.status = status;\n        this.department = department;\n    }\n\n    // Abstract method - each subclass returns its own hourly fee (Req3, Req4)\n    public abstract double getFeeRate();\n\n    // Getters and Setters\n    public String getUserID() { return userID; }\n    public void setUserID(String userID) { this.userID = userID; }\n\n    public String getName() { return name; }\n    public void setName(String name) { this.name = name; }\n\n    public String getEmail() { return email; }\n    public void setEmail(String email) { this.email = email; }\n\n    public String getPassword() { return password; }\n    public void setPassword(String password) { this.password = password; }\n\n    public String getUserType() { return userType; }\n    public void setUserType(String userType) { this.userType = userType; }\n\n    public String getStaffID() { return staffID; }\n    public void setStaffID(String staffID) { this.staffID = staffID; }\n\n    public String getStatus() { return status; }\n    public void setStatus(String status) { this.status = status; }\n\n    public String getDepartment() { return department; }\n    public void setDepartment(String department) { this.department = department; }\n\n    @Override\n    public String toString() {\n        return \"User [\" + userID + \", \" + name + \", \" + email + \", \" + userType + \", \" + status + \"]\";\n    }\n}\n"
  },
  {
    "path": "D2/src/pattern/command/.gitkeep",
    "content": ""
  },
  {
    "path": "D2/src/pattern/command/CancelCommand.java",
    "content": "package pattern.command;\n\nimport model.Reservation;\n\npublic class CancelCommand implements Command {\n\n    private ReservationService reservationService;\n    private Reservation reservation;\n\n    public CancelCommand(ReservationService reservationService, Reservation reservation) {\n        this.reservationService = reservationService;\n        this.reservation = reservation;\n    }\n\n    @Override\n    public void execute() {\n        reservationService.cancel(reservation);\n    }\n}"
  },
  {
    "path": "D2/src/pattern/command/Command.java",
    "content": "package pattern.command;\n\npublic interface Command {\n    void execute();\n}"
  },
  {
    "path": "D2/src/pattern/command/ExtendCommand.java",
    "content": "package pattern.command;\n\nimport model.Reservation;\n\npublic class ExtendCommand implements Command {\n\n    private ReservationService reservationService;\n    private Reservation reservation;\n    private String newEndTime;\n\n    public ExtendCommand(ReservationService reservationService, Reservation reservation, String newEndTime) {\n        this.reservationService = reservationService;\n        this.reservation = reservation;\n        this.newEndTime = newEndTime;\n    }\n\n    @Override\n    public void execute() {\n        reservationService.extend(reservation, newEndTime);\n    }\n}"
  },
  {
    "path": "D2/src/pattern/command/ForfeitDepositCommand.java",
    "content": "package pattern.command;\n\nimport model.Reservation;\n\npublic class ForfeitDepositCommand implements Command {\n\n    private ReservationService reservationService;\n    private Reservation reservation;\n\n    public ForfeitDepositCommand(ReservationService reservationService, Reservation reservation) {\n        this.reservationService = reservationService;\n        this.reservation = reservation;\n    }\n\n    @Override\n    public void execute() {\n        reservationService.forfeitDeposit(reservation);\n    }\n}"
  },
  {
    "path": "D2/src/pattern/command/ModifyCommand.java",
    "content": "package pattern.command;\n\nimport model.Reservation;\n\npublic class ModifyCommand implements Command {\n\n    private ReservationService reservationService;\n    private Reservation reservation;\n    private String newStartTime;\n    private String newEndTime;\n\n    public ModifyCommand(ReservationService reservationService, Reservation reservation, String newStartTime, String newEndTime) {\n        this.reservationService = reservationService;\n        this.reservation = reservation;\n        this.newStartTime = newStartTime;\n        this.newEndTime = newEndTime;\n    }\n\n    @Override\n    public void execute() {\n        reservationService.modify(reservation, newStartTime, newEndTime);\n    }\n}"
  },
  {
    "path": "D2/src/pattern/command/ReservationService.java",
    "content": "package pattern.command;\n\nimport model.Reservation;\n\npublic class ReservationService {\n\n    public void reserve(Reservation reservation) {\n        reservation.setStatus(\"CONFIRMED\");\n        System.out.println(\"Reservation \" + reservation.getBookingID() + \" created for equipment \" + reservation.getEquipmentID());\n    }\n\n    public void cancel(Reservation reservation) {\n        reservation.cancel();\n        System.out.println(\"Reservation \" + reservation.getBookingID() + \" cancelled.\");\n    }\n\n    public void modify(Reservation reservation, String newStartTime, String newEndTime) {\n        reservation.setStartTime(newStartTime);\n        reservation.setEndTime(newEndTime);\n        System.out.println(\"Reservation \" + reservation.getBookingID() + \" modified.\");\n    }\n\n    public void extend(Reservation reservation, String newEndTime) {\n        reservation.extend(newEndTime);\n        System.out.println(\"Reservation \" + reservation.getBookingID() + \" extended to \" + newEndTime);\n    }\n\n    public void forfeitDeposit(Reservation reservation) {\n        reservation.forfeitDeposit();\n        System.out.println(\"Deposit forfeited for reservation \" + reservation.getBookingID());\n    }\n}"
  },
  {
    "path": "D2/src/pattern/command/ReserveCommand.java",
    "content": "package pattern.command;\n\nimport model.Reservation;\n\npublic class ReserveCommand implements Command {\n\n    private ReservationService reservationService;\n    private Reservation reservation;\n\n    public ReserveCommand(ReservationService reservationService, Reservation reservation) {\n        this.reservationService = reservationService;\n        this.reservation = reservation;\n    }\n\n    @Override\n    public void execute() {\n        reservationService.reserve(reservation);\n    }\n}"
  },
  {
    "path": "D2/src/pattern/factory/.gitkeep",
    "content": ""
  },
  {
    "path": "D2/src/pattern/factory/UserFactory.java",
    "content": "package pattern.factory;\nimport model.User;\nimport model.Student; \nimport model.Faculty;\nimport model.Guest;\nimport model.Researcher;\nimport model.HeadLabCoordinator;\nimport model.LabManager;;\n\npublic class UserFactory {\n\n    public UserFactory () {}\n\n    public User getUserType(String userType) {\n        if (userType.equals(\"STUDENT\")) {\n            return new Student();\n        }\n        else if (userType.equals(\"GUEST\")) {\n            return new Guest(); \n        }\n\n        else if (userType.equals(\"RESEARCHER\")) {\n            return new Researcher();\n        }\n\n        else if (userType.equals(\"FACULTY\")) {\n            return new Faculty();\n        }\n\n        else if (userType.equals(\"COORDINATOR\")) {\n            return new HeadLabCoordinator();\n        }\n\n        else if (userType.equals(\"MANAGER\")) {\n            return new LabManager();\n        }\n        else {\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "D2/src/pattern/observer/.gitkeep",
    "content": ""
  },
  {
    "path": "D2/src/pattern/observer/EquipmentObserver.java",
    "content": "package pattern.observer;\n\n/**\n * Observer Pattern - Observer Interface\n * Any class that wants to be notified of equipment status changes implements this.\n */\npublic interface EquipmentObserver {\n    void update(String equipmentID, String newStatus);\n}\n"
  },
  {
    "path": "D2/src/pattern/observer/EquipmentSubject.java",
    "content": "package pattern.observer;\n\n/**\n * Observer Pattern - Subject Interface\n * EquipmentContext implements this to support registering/notifying observers.\n */\npublic interface EquipmentSubject {\n    void registerObserver(EquipmentObserver observer);\n    void removeObserver(EquipmentObserver observer);\n    void notifyObservers(String equipmentID, String newStatus);\n}\n"
  },
  {
    "path": "D2/src/pattern/observer/Observer.java",
    "content": ""
  },
  {
    "path": "D2/src/pattern/observer/UserNotificationObserver.java",
    "content": "package pattern.observer;\n\nimport model.User;\nimport java.util.List;\n\n/**\n * Observer Pattern - Concrete Observer\n * Notifies affected users when equipment status changes (Req5, Req6).\n * For example: if equipment is DISABLED or set to MAINTENANCE,\n * users with active bookings on that equipment get notified.\n */\npublic class UserNotificationObserver implements EquipmentObserver {\n\n    private List<User> affectedUsers;\n    private String notificationLog = \"\";\n\n    public UserNotificationObserver(List<User> affectedUsers) {\n        this.affectedUsers = affectedUsers;\n    }\n\n    @Override\n    public void update(String equipmentID, String newStatus) {\n        if (newStatus.equals(\"DISABLED\") || newStatus.equals(\"MAINTENANCE\")) {\n            for (User user : affectedUsers) {\n                String message = \"[NOTIFICATION] Dear \" + user.getName() +\n                        \", equipment \" + equipmentID +\n                        \" has been marked as \" + newStatus +\n                        \". Your booking may be affected.\";\n                System.out.println(message);\n                notificationLog += message + \"\\n\";\n            }\n        }\n    }\n\n    public String getNotificationLog() {\n        return notificationLog;\n    }\n\n    public void setAffectedUsers(List<User> affectedUsers) {\n        this.affectedUsers = affectedUsers;\n    }\n}\n"
  },
  {
    "path": "D2/src/pattern/singleton/.gitkeep",
    "content": ""
  },
  {
    "path": "D2/src/pattern/singleton/BookingSystem.java",
    "content": "package pattern.singleton;\nimport model.Reservation;\nimport java.util.ArrayList;\nimport java.time.LocalDateTime;\nimport java.util.List;\n\npublic class BookingSystem {\n\n    // creating the single BookingSystem instance\n    private static BookingSystem bsInstance = new BookingSystem();\n    public static BookingSystem getInstance() { return bsInstance; }\n\n    private List<Reservation> reservations;\n\n    // Setting the constructor private so nobody outside the class can call it\n    private BookingSystem() {\n        bsInstance.reservations = new ArrayList<Reservation>();\n    }\n\n    public List<Reservation> getReservations() { return bsInstance.reservations; }\n\n    public void addBooking(Reservation booking) {\n        bsInstance.getReservations().add(booking);\n    }\n\n    public boolean checkActiveBookings(String equipmentID) {\n        Reservation booking;\n        for (int i = 0; i < bsInstance.reservations.size(); i++) {\n            booking = reservations.get(i);\n            if (booking.getEquipmentID().equals(equipmentID)) {\n                System.out.println(booking.toString());\n                return true;\n            }\n        }\n        System.out.println(\"No reservation with that equipment ID.\\n\");\n        return false;\n    }\n\n    public void cancelFutureBookings(String id) {\n        Reservation booking;\n        for (int i = 0; i < bsInstance.reservations.size(); i++) {\n            booking = reservations.get(i);\n            LocalDateTime start = LocalDateTime.parse(booking.getStartTime());\n            if (booking.getEquipmentID().equals(id) && LocalDateTime.now().isBefore(start)) {\n\n                if (booking.getStatus().equals(\"CANCELLED\")) { reservations.remove(i); }\n                return;\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "D2/src/pattern/singleton/HeadLabCoordinatorSingleton.java",
    "content": "package pattern.singleton;\n\nimport model.LabManager;\n\n/**\n * Singleton Pattern - HeadLabCoordinator\n * Only one Head Lab Coordinator exists in the system (Req2).\n * Only this instance can generate manager accounts.\n */\npublic class HeadLabCoordinatorSingleton {\n\n    private static HeadLabCoordinatorSingleton instance;\n\n    private String coordinatorID;\n    private String name;\n    private String email;\n    private String department;\n\n    // Private constructor - nobody can instantiate this directly\n    private HeadLabCoordinatorSingleton() {\n        this.coordinatorID = \"C001\";\n        this.name = \"Coordinator Carol\";\n        this.email = \"coord@yorku.ca\";\n        this.department = \"Administration\";\n    }\n\n    // Only way to get the coordinator instance\n    public static HeadLabCoordinatorSingleton getInstance() {\n        if (instance == null) {\n            instance = new HeadLabCoordinatorSingleton();\n        }\n        return instance;\n    }\n\n    /**\n     * Req2 - Auto-generate a lab manager account.\n     * Only the Head Lab Coordinator can do this.\n     */\n    public LabManager generateManagerAccount(String managerID, String name,\n                                              String email, String tempPassword,\n                                              String department) {\n        System.out.println(\"[COORDINATOR] Generating manager account for: \" + name);\n        return new LabManager(managerID, name, email, tempPassword, managerID, department);\n    }\n\n    // Getters\n    public String getCoordinatorID() { return coordinatorID; }\n    public String getName() { return name; }\n    public String getEmail() { return email; }\n    public String getDepartment() { return department; }\n\n    @Override\n    public String toString() {\n        return \"HeadLabCoordinator [\" + coordinatorID + \"] \" + name;\n    }\n}\n"
  },
  {
    "path": "D2/src/pattern/state/.gitkeep",
    "content": ""
  },
  {
    "path": "D2/src/pattern/state/AvailableState.java",
    "content": "package pattern.state;\n\npublic class AvailableState implements EquipmentState {\n\n    @Override\n    public void enable(EquipmentContext context) {\n        System.out.println(\"Equipment is already enabled and available.\");\n    }\n\n    @Override\n    public void disable(EquipmentContext context) {\n        context.setState(new DisabledState());\n        System.out.println(\"Equipment has been disabled.\");\n    }\n\n    @Override\n    public void markUnderMaintenance(EquipmentContext context) {\n        context.setState(new MaintenanceState());\n        System.out.println(\"Equipment is now under maintenance.\");\n    }\n\n    @Override\n    public String getStatus() {\n        return \"AVAILABLE\";\n    }\n}"
  },
  {
    "path": "D2/src/pattern/state/DisabledState.java",
    "content": "package pattern.state;\n\npublic class DisabledState implements EquipmentState {\n\n    @Override\n    public void enable(EquipmentContext context) {\n        context.setState(new AvailableState());\n        System.out.println(\"Equipment has been enabled and is now available.\");\n    }\n\n    @Override\n    public void disable(EquipmentContext context) {\n        System.out.println(\"Equipment is already disabled.\");\n    }\n\n    @Override\n    public void markUnderMaintenance(EquipmentContext context) {\n        context.setState(new MaintenanceState());\n        System.out.println(\"Equipment moved from disabled to maintenance.\");\n    }\n\n    @Override\n    public String getStatus() {\n        return \"DISABLED\";\n    }\n}"
  },
  {
    "path": "D2/src/pattern/state/EquipmentContext.java",
    "content": "package pattern.state;\n\nimport pattern.observer.EquipmentObserver;\nimport pattern.observer.EquipmentSubject;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * State Pattern - Context class\n * Holds the current state of a piece of equipment.\n * Also implements EquipmentSubject (Observer Pattern) to notify\n * observers when the equipment status changes (Req5, Req6).\n */\npublic class EquipmentContext implements EquipmentSubject {\n\n    private EquipmentState currentState;\n    private String equipmentID;\n\n    // Observer pattern - list of observers watching this equipment\n    private List<EquipmentObserver> observers = new ArrayList<>();\n\n    public EquipmentContext(String equipmentID, String initialStatus) {\n        this.equipmentID = equipmentID;\n        this.currentState = getStateFromString(initialStatus);\n    }\n\n    // --- State Pattern methods ---\n\n    public void enable() {\n        currentState.enable(this);\n    }\n\n    public void disable() {\n        currentState.disable(this);\n    }\n\n    public void markUnderMaintenance() {\n        currentState.markUnderMaintenance(this);\n    }\n\n    public void setState(EquipmentState newState) {\n        this.currentState = newState;\n        notifyObservers(equipmentID, getStatusString());\n    }\n\n    public EquipmentState getCurrentState() {\n        return currentState;\n    }\n\n    public String getStatusString() {\n        if (currentState instanceof AvailableState)    return \"AVAILABLE\";\n        if (currentState instanceof DisabledState)     return \"DISABLED\";\n        if (currentState instanceof MaintenanceState)  return \"MAINTENANCE\";\n        return \"UNKNOWN\";\n    }\n\n    public String getEquipmentID() {\n        return equipmentID;\n    }\n\n    // --- Observer Pattern methods ---\n\n    @Override\n    public void registerObserver(EquipmentObserver observer) {\n        observers.add(observer);\n    }\n\n    @Override\n    public void removeObserver(EquipmentObserver observer) {\n        observers.remove(observer);\n    }\n\n    @Override\n    public void notifyObservers(String equipmentID, String newStatus) {\n        for (EquipmentObserver observer : observers) {\n            observer.update(equipmentID, newStatus);\n        }\n    }\n\n    // Helper to convert string to State object\n    private EquipmentState getStateFromString(String status) {\n        switch (status.toUpperCase()) {\n            case \"AVAILABLE\":   return new AvailableState();\n            case \"DISABLED\":    return new DisabledState();\n            case \"MAINTENANCE\": return new MaintenanceState();\n            default:            return new AvailableState();\n        }\n    }\n}"
  },
  {
    "path": "D2/src/pattern/state/EquipmentState.java",
    "content": "package pattern.state;\n\npublic interface EquipmentState {\n    void enable(EquipmentContext context);\n    void disable(EquipmentContext context);\n    void markUnderMaintenance(EquipmentContext context);\n    String getStatus();\n}"
  },
  {
    "path": "D2/src/pattern/state/MaintenanceState.java",
    "content": "package pattern.state;\n\npublic class MaintenanceState implements EquipmentState {\n\n    @Override\n    public void enable(EquipmentContext context) {\n        context.setState(new AvailableState());\n        System.out.println(\"Maintenance completed. Equipment is now available.\");\n    }\n\n    @Override\n    public void disable(EquipmentContext context) {\n        context.setState(new DisabledState());\n        System.out.println(\"Equipment has been disabled from maintenance state.\");\n    }\n\n    @Override\n    public void markUnderMaintenance(EquipmentContext context) {\n        System.out.println(\"Equipment is already under maintenance.\");\n    }\n\n    @Override\n    public String getStatus() {\n        return \"MAINTENANCE\";\n    }\n}"
  },
  {
    "path": "D2/src/pattern/strategy/.gitkeep",
    "content": ""
  },
  {
    "path": "D2/src/pattern/strategy/CreditCardPayment.java",
    "content": "package pattern.strategy;\n\nimport model.PaymentTransaction;\n\npublic class CreditCardPayment implements PaymentStrategy {\n\n    @Override\n    public boolean pay(PaymentTransaction transaction) {\n        System.out.println(\"Processing credit card payment of $\" + transaction.getTotalAmount());\n        transaction.setPaymentStatus(\"SUCCESS\");\n        return true;\n    }\n}"
  },
  {
    "path": "D2/src/pattern/strategy/DebitPayment.java",
    "content": "package pattern.strategy;\n\nimport model.PaymentTransaction;\n\npublic class DebitPayment implements PaymentStrategy {\n\n    @Override\n    public boolean pay(PaymentTransaction transaction) {\n        System.out.println(\"Processing debit payment of $\" + transaction.getTotalAmount());\n        transaction.setPaymentStatus(\"SUCCESS\");\n        return true;\n    }\n} "
  },
  {
    "path": "D2/src/pattern/strategy/GrantPayment.java",
    "content": "package pattern.strategy;\n\nimport model.PaymentTransaction;\n\npublic class GrantPayment implements PaymentStrategy {\n\n    @Override\n    public boolean pay(PaymentTransaction transaction) {\n        System.out.println(\"Processing grant payment for booking \" + transaction.getBookingID());\n        transaction.setPaymentStatus(\"SUCCESS\");\n        return true;\n    }\n}"
  },
  {
    "path": "D2/src/pattern/strategy/InstitutionalPayment.java",
    "content": "package pattern.strategy;\n\nimport model.PaymentTransaction;\n\npublic class InstitutionalPayment implements PaymentStrategy {\n\n    @Override\n    public boolean pay(PaymentTransaction transaction) {\n        System.out.println(\"Processing institutional payment for booking \" + transaction.getBookingID());\n        transaction.setPaymentStatus(\"SUCCESS\");\n        return true;\n    }\n}"
  },
  {
    "path": "D2/src/pattern/strategy/PaymentProcessor.java",
    "content": "package pattern.strategy;\n\nimport model.PaymentTransaction;\n\npublic class PaymentProcessor {\n    private PaymentStrategy paymentStrategy;\n\n    public PaymentProcessor(PaymentStrategy paymentStrategy) {\n        this.paymentStrategy = paymentStrategy;\n    }\n\n    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {\n        this.paymentStrategy = paymentStrategy;\n    }\n\n    public boolean processPayment(PaymentTransaction transaction) {\n        if (paymentStrategy == null) {\n            transaction.setPaymentStatus(\"DECLINED\");\n            return false;\n        }\n        return paymentStrategy.pay(transaction);\n    }\n}"
  },
  {
    "path": "D2/src/pattern/strategy/PaymentStrategy.java",
    "content": "package pattern.strategy;\n\nimport model.PaymentTransaction;\n\npublic interface PaymentStrategy {\n    boolean pay(PaymentTransaction transaction);\n}"
  }
]