[{"data":1,"prerenderedAt":12612},["ShallowReactive",2],{"content-page:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox":3,"content-page-quiz:none":2787,"book-module-total-pages":2788,"content-section-pages:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F":2789,"content-directory-pages:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox":12611},{"id":4,"title":5,"audience":6,"body":7,"contentType":2762,"course":2763,"description":2764,"estimateBasis":2765,"estimatedDiscussionMinutes":2766,"estimatedLiveMinutes":2767,"estimatedTotalMinutes":2768,"extension":871,"meta":2769,"module":569,"navigation":2770,"order":2771,"path":2772,"promptAssist":2773,"seo":2774,"status":2775,"stem":2776,"tags":2777,"videoDuration":2782,"videoId":2783,"videoLink":2784,"videoTitle":2785,"week":569,"__hash__":2786},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox.md","Local Ubuntu Web Server With VirtualBox","student",{"type":8,"value":9,"toc":2693},"minimark",[10,46,92,130,203,235,262,304,330,359,388,415,446,475,513,580,615,662,705,749,798,862,901,936,973,1006,1043,1076,1106,1136,1166,1196,1226,1261,1293,1326,1359,1408,1411,1455,1481,1522,1579,1661,1712,1745,1775,1805,1858,1885,1936,1984,2042,2102,2143,2173,2210,2245,2281,2333,2386,2405,2433,2481,2554,2662],[11,12,15,19],"slide",{"id":13,"level":14},"virtualbox-title","2",[16,17,5],"h2",{"id":18},"local-ubuntu-web-server-with-virtualbox",[20,21,22,26,29,32,35,43],"ul",{},[23,24,25],"li",{},"Primary course path for the local Ubuntu VM",[23,27,28],{},"Create an Ubuntu Server VM in VirtualBox",[23,30,31],{},"Connect from your host terminal with SSH",[23,33,34],{},"Share the course repo into Ubuntu",[23,36,37,38,42],{},"Serve ",[39,40,41],"code",{},"public_html"," through Apache and PHP",[23,44,45],{},"Create a local MySQL database for testing",[11,47,49,52,56,67,70],{"id":48,"level":14},"main-goal",[16,50,51],{"id":48},"Main Goal",[53,54,55],"p",{},"Your host computer and Ubuntu VM have different jobs:",[20,57,58,61,64],{},[23,59,60],{},"Host computer: edit files with VS Code and open the browser",[23,62,63],{},"Ubuntu VM: run Apache, PHP, MySQL, and server commands",[23,65,66],{},"Shared folder: lets both use the same course repo files",[53,68,69],{},"Target result:",[20,71,72,78,83,86,89],{},[23,73,74,75],{},"Host browser opens ",[39,76,77],{},"http:\u002F\u002Flocalhost:3000",[23,79,80,81],{},"Apache serves the repo's ",[39,82,41],{},[23,84,85],{},"PHP executes inside Ubuntu",[23,87,88],{},"Local MySQL has a database and user named after your UCID",[23,90,91],{},"Edits made on the host appear after browser refresh",[11,93,95,98,101,120,123],{"id":94,"level":14},"virtualbox-caveat",[16,96,97],{"id":94},"VirtualBox Caveat",[53,99,100],{},"VirtualBox is the primary local VM path for this course:",[20,102,103,106,109,117],{},[23,104,105],{},"Works well on modern Windows, Linux, and Intel Mac hosts",[23,107,108],{},"Apple Silicon Mac requires an ARM64 Ubuntu Server ISO",[23,110,111,112],{},"Windows on Arm support is experimental in VirtualBox\n",[20,113,114],{},[23,115,116],{},"Avoid unless your instructor confirms it for your machine",[23,118,119],{},"Arm hosts cannot run x86\u002FAMD64 guest images",[53,121,122],{},"VMware is the fallback path if VirtualBox is not a good fit for your machine",[124,125,127],"admonition",{"type":126},"tip",[53,128,129],{},"Most students do not need BIOS changes. If VirtualBox cannot start the VM or does not offer a 64-bit Ubuntu option, check that Intel VT-x, AMD-V, or SVM is enabled in BIOS\u002FUEFI. On Windows, Hyper-V-related features can also interfere on some systems.",[11,131,133,136],{"id":132,"level":14},"before-you-start",[16,134,135],{"id":132},"Before You Start",[20,137,138,158,176,179,182,185,200],{},[23,139,140,141],{},"VirtualBox downloaded\n",[20,142,143,152,155],{},[23,144,145],{},[146,147,151],"a",{"href":148,"rel":149},"https:\u002F\u002Fwww.virtualbox.org\u002Fwiki\u002FDownloads",[150],"nofollow","VirtualBox downloads",[23,153,154],{},"Windows\u002FLinux\u002FIntel Mac: use the standard host installer",[23,156,157],{},"Apple Silicon Mac: use the macOS Arm64 host installer",[23,159,160,161],{},"Ubuntu Server ISO downloaded\n",[20,162,163,170,173],{},[23,164,165],{},[146,166,169],{"href":167,"rel":168},"https:\u002F\u002Fubuntu.com\u002Fdownload\u002Fserver#how-to-install-tab-lts",[150],"Ubuntu Server installer",[23,171,172],{},"Apple Silicon Mac: use the ARM64 server ISO",[23,174,175],{},"Windows, Linux, and Intel Mac: use the AMD64 server ISO",[23,177,178],{},"Internet Applications course repo cloned on host computer",[23,180,181],{},"Git\u002FGitHub setup already working",[23,183,184],{},"Administrator access on your computer",[23,186,187,188,191,192],{},"At least ",[39,189,190],{},"10 GB"," free disk space for the VM\n",[20,193,194],{},[23,195,196,199],{},[39,197,198],{},"20-25 GB"," is safer if your computer has room",[23,201,202],{},"Stable internet for package installs",[11,204,206,209],{"id":205,"level":14},"setup-parts",[16,207,208],{"id":205},"Setup Parts",[20,210,211,214,217,220,226,229,232],{},[23,212,213],{},"VM: Ubuntu Server running inside VirtualBox",[23,215,216],{},"NAT adapter: gives the VM internet access",[23,218,219],{},"Port forwarding: lets the host reach SSH and Apache",[23,221,222,223],{},"SSH: lets the host terminal control Ubuntu through ",[39,224,225],{},"localhost",[23,227,228],{},"Shared folder: exposes the host repo inside Ubuntu",[23,230,231],{},"Apache\u002FPHP: serves and executes the web app",[23,233,234],{},"MySQL: local database server for local testing",[11,236,238,242],{"id":237,"level":14},"install-virtualbox-windows",[16,239,241],{"id":240},"install-virtualbox-on-windows","Install VirtualBox On Windows",[20,243,244,247,250,253,256,259],{},[23,245,246],{},"Download VirtualBox for Windows hosts",[23,248,249],{},"Run the installer as an administrator if prompted",[23,251,252],{},"Keep the default install path and features",[23,254,255],{},"Accept the network reset warning",[23,257,258],{},"Open VirtualBox after installation",[23,260,261],{},"See the slides below for the Windows installer screens",[11,263,266,269],{"id":264,"level":265},"windows-installer-start","3",[16,267,268],{"id":264},"Windows Installer: Start",[270,271,276,288],"two-col",{"gap":272,"left-width":273,"right-width":274,"stack":275},"lg","1.4fr","0.9fr","never",[277,278,280],"template",{"v-slot:left":279},"",[53,281,282],{},[283,284],"img",{"alt":285,"src":286,"variant":287},"VirtualBox Windows installer start screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step1.png","sidecar-screenshot",[277,289,290],{"v-slot:right":279},[20,291,292,298,301],{},[23,293,294,295],{},"Launch the downloaded ",[39,296,297],{},".exe",[23,299,300],{},"Approve the Windows security prompt if shown",[23,302,303],{},"Start the setup wizard",[11,305,307,310],{"id":306,"level":265},"windows-installer-features",[16,308,309],{"id":306},"Windows Installer: Features",[270,311,312,320],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,313,314],{"v-slot:left":279},[53,315,316],{},[283,317],{"alt":318,"src":319,"variant":287},"VirtualBox Windows installer feature selection screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step2.png",[277,321,322],{"v-slot:right":279},[20,323,324,327],{},[23,325,326],{},"Keep the default install location",[23,328,329],{},"Keep the default features selected",[11,331,333,336],{"id":332,"level":265},"windows-installer-network-warning",[16,334,335],{"id":332},"Windows Installer: Network Warning",[270,337,338,346],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,339,340],{"v-slot:left":279},[53,341,342],{},[283,343],{"alt":344,"src":345,"variant":287},"VirtualBox Windows installer network warning","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step3.png",[277,347,348],{"v-slot:right":279},[20,349,350,353,356],{},[23,351,352],{},"VirtualBox may reset network adapters briefly",[23,354,355],{},"This is expected during install",[23,357,358],{},"Save web work before continuing if needed",[11,360,362,365],{"id":361,"level":265},"windows-installer-ready",[16,363,364],{"id":361},"Windows Installer: Ready",[270,366,367,375],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,368,369],{"v-slot:left":279},[53,370,371],{},[283,372],{"alt":373,"src":374,"variant":287},"VirtualBox Windows installer ready screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step4.png",[277,376,377],{"v-slot:right":279},[20,378,379,382,385],{},[23,380,381],{},"Start the installation",[23,383,384],{},"Keep the default choices",[23,386,387],{},"Wait for the installer to request permissions if needed",[11,389,391,395],{"id":390,"level":265},"windows-installer-progress",[16,392,394],{"id":393},"windows-installer-start-options","Windows Installer: Start Options",[270,396,397,405],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,398,399],{"v-slot:left":279},[53,400,401],{},[283,402],{"alt":403,"src":404,"variant":287},"VirtualBox Windows installer progress screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step5.png",[277,406,407],{"v-slot:right":279},[20,408,409,412],{},[23,410,411],{},"No need to create a Start Menu item or desktop shortcut unless desired",[23,413,414],{},"Third option is likely optional too since we'll be using the VirtualBox Manager",[11,416,418,421],{"id":417,"level":265},"windows-installer-permission",[16,419,420],{"id":417},"Windows Installer: Permission",[270,422,423,431],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,424,425],{"v-slot:left":279},[53,426,427],{},[283,428],{"alt":429,"src":430,"variant":287},"VirtualBox Windows installer permission prompt","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step6.png",[277,432,433],{"v-slot:right":279},[20,434,435,438],{},[23,436,437],{},"Proceed with install",[23,439,440,441],{},"Approve VirtualBox driver prompts\n",[20,442,443],{},[23,444,445],{},"These let VirtualBox create virtual hardware",[11,447,449,452],{"id":448,"level":265},"windows-installer-complete",[16,450,451],{"id":448},"Windows Installer: Complete",[270,453,454,462],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,455,456],{"v-slot:left":279},[53,457,458],{},[283,459],{"alt":460,"src":461,"variant":287},"VirtualBox Windows installer completion screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step7.png",[277,463,464],{"v-slot:right":279},[20,465,466,469,472],{},[23,467,468],{},"Finish the installer",[23,470,471],{},"Open VirtualBox",[23,473,474],{},"Continue to VM creation",[11,476,478,482],{"id":477,"level":14},"install-virtualbox-macos",[16,479,481],{"id":480},"install-virtualbox-on-macos","Install VirtualBox On macOS",[270,483,486,505],{"gap":272,"left-width":484,"right-width":485,"stack":275},"0.95fr","1.05fr",[277,487,488],{"v-slot:left":279},[20,489,490,493,496,499,502],{},[23,491,492],{},"Install the VirtualBox host package for your Mac CPU type",[23,494,495],{},"Intel Mac: standard macOS host installer",[23,497,498],{},"Apple Silicon Mac: Arm64 host installer and Arm64 Ubuntu Server ISO",[23,500,501],{},"Approve macOS security prompts if needed",[23,503,504],{},"If VirtualBox is not a good fit, use the VMware fallback lesson",[277,506,507],{"v-slot:right":279},[53,508,509],{},[283,510],{"alt":511,"src":512,"variant":287},"Summary of macOS VirtualBox setup notes","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvm_summary_mac.png",[11,514,516,520,523],{"id":515,"level":14},"step-1-create-vm",[16,517,519],{"id":518},"step-1-create-the-vm","Step 1: Create The VM",[53,521,522],{},"Create a lightweight Ubuntu Server VM:",[20,524,525,528,536,552,564,571,574,577],{},[23,526,527],{},"Type: Linux",[23,529,530,531],{},"Version: Ubuntu 64-bit or Ubuntu Arm64\n",[20,532,533],{},[23,534,535],{},"Match the version to the ISO you downloaded",[23,537,538,539,542,543],{},"Memory: ",[39,540,541],{},"1 GB"," course target\n",[20,544,545],{},[23,546,547,548,551],{},"Use ",[39,549,550],{},"1.5-2 GB"," if the installer is too slow or refuses to continue (you shouldn't need to do this)",[23,553,554,555,557,558],{},"Disk: ",[39,556,190],{}," course minimum\n",[20,559,560],{},[23,561,562,199],{},[39,563,198],{},[23,565,566,567,570],{},"CPU: ",[39,568,569],{},"1"," core is enough for this course VM",[23,572,573],{},"Enable OpenSSH during install if prompted",[23,575,576],{},"Username: use your UCID",[23,578,579],{},"See the slides below for VM settings and Ubuntu install screens",[11,581,583,586],{"id":582,"level":265},"vm-setup-name-and-iso",[16,584,585],{"id":582},"VM Setup: Name And ISO",[270,587,588,596],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,589,590],{"v-slot:left":279},[53,591,592],{},[283,593],{"alt":594,"src":595,"variant":287},"VirtualBox VM name and ISO setup","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_1.png",[277,597,598],{"v-slot:right":279},[20,599,600,603,609,612],{},[23,601,602],{},"Start a new virtual machine",[23,604,605,606],{},"Name it clearly, such as ",[39,607,608],{},"it202-vm",[23,610,611],{},"Choose the Ubuntu Server ISO file next",[23,613,614],{},"OS fields may look wrong until the ISO is selected",[11,616,618,621],{"id":617,"level":265},"vm-setup-confirm-ubuntu-iso",[16,619,620],{"id":617},"VM Setup: Confirm Ubuntu ISO",[270,622,623,631],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,624,625],{"v-slot:left":279},[53,626,627],{},[283,628],{"alt":629,"src":630,"variant":287},"VirtualBox VM name and Ubuntu ISO selected","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_2.png",[277,632,633],{"v-slot:right":279},[20,634,635,641,647,650],{},[23,636,637,638],{},"Confirm OS is ",[39,639,640],{},"Linux",[23,642,643,644],{},"Confirm distribution is ",[39,645,646],{},"Ubuntu",[23,648,649],{},"Confirm version matches your ISO",[23,651,652,653,656,657],{},"Keep ",[39,654,655],{},"Unattended Installation"," off\n",[20,658,659],{},[23,660,661],{},"The Ubuntu installer screens are easier to teach manually",[11,663,665,668],{"id":664,"level":265},"vm-setup-memory-and-cpu",[16,666,667],{"id":664},"VM Setup: Memory And CPU",[270,669,670,678],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,671,672],{"v-slot:left":279},[53,673,674],{},[283,675],{"alt":676,"src":677,"variant":287},"VirtualBox VM memory and CPU settings","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_4.png",[277,679,680],{"v-slot:right":279},[20,681,682,695,699,702],{},[23,683,538,684,542,687],{},[39,685,686],{},"1024 MB",[20,688,689,692],{},[23,690,691],{},"The goal is to match free-tier cloud services",[23,693,694],{},"Demonstrates that small apps can run with limited resources",[23,696,566,697],{},[39,698,569],{},[23,700,701],{},"Keep EFI off unless your machine requires it",[23,703,704],{},"This VM is for Apache, PHP, MySQL, and local development\u002Ftesting",[11,706,708,711],{"id":707,"level":265},"vm-setup-virtual-disk",[16,709,710],{"id":707},"VM Setup: Virtual Disk",[270,712,713,721],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,714,715],{"v-slot:left":279},[53,716,717],{},[283,718],{"alt":719,"src":720,"variant":287},"VirtualBox virtual hard disk settings","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_5.png",[277,722,723],{"v-slot:right":279},[20,724,725,731,734,746],{},[23,726,727,728],{},"Disk type: ",[39,729,730],{},"VDI",[23,732,733],{},"Storage: dynamically allocated",[23,735,736,737,739],{},"Minimum: ",[39,738,190],{},[20,740,741],{},[23,742,743,745],{},[39,744,198],{}," is safer if you have room",[23,747,748],{},"Dynamic disk uses space as needed, not all at once",[11,750,752,755],{"id":751,"level":265},"vm-setup-start-with-gui",[16,753,754],{"id":751},"VM Setup: Start With GUI",[270,756,757,765],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,758,759],{"v-slot:left":279},[53,760,761],{},[283,762],{"alt":763,"src":764,"variant":287},"VirtualBox VM selected with the Start button visible","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_6.png",[277,766,767],{"v-slot:right":279},[20,768,769,772,783,786],{},[23,770,771],{},"Select the newly created VM",[23,773,774,775,778],{},"Click ",[39,776,777],{},"Start",[20,779,780],{},[23,781,782],{},"Choose the normal GUI start for the first boot",[23,784,785],{},"Complete the Ubuntu installer in the VM window",[23,787,788,789],{},"After install and SSH setup, future starts can be headless\n",[20,790,791],{},[23,792,793,794,797],{},"You will connect with ",[39,795,796],{},"ssh"," when you need the VM",[11,799,801,805,808],{"id":800,"level":14},"ubuntu-installer",[16,802,804],{"id":803},"step-2-ubuntu-installer","Step 2: Ubuntu Installer",[53,806,807],{},"Use the Ubuntu Server installer after the VM starts:",[20,809,810,813,816,819,822,825,859],{},[23,811,812],{},"Choose the default course options unless noted",[23,814,815],{},"Continue without updating the installer if instructed",[23,817,818],{},"Use your UCID for the Ubuntu username",[23,820,821],{},"Install OpenSSH server during setup",[23,823,824],{},"Skip optional server snaps",[23,826,827,828],{},"Keyboard navigation:\n",[20,829,830,837,847,853],{},[23,831,832,836],{},[833,834,835],"kbd",{},"Tab"," moves between fields and buttons",[23,838,839,842,843,846],{},[833,840,841],{},"Up"," \u002F ",[833,844,845],{},"Down"," moves through lists",[23,848,849,852],{},[833,850,851],{},"Space"," toggles checkboxes",[23,854,855,858],{},[833,856,857],{},"Enter"," confirms the selected option",[23,860,861],{},"See the slides below for the installer screens",[11,863,865,869],{"id":864,"level":265},"ubuntu-installer-boot-menu",[16,866,868],{"id":867},"step-21-boot-menu","Step 2.1: Boot Menu",[270,870,874,883],{"gap":871,"left-width":872,"right-width":873,"stack":275},"md","1.75fr","0.65fr",[277,875,876],{"v-slot:left":279},[53,877,878],{},[283,879],{"alt":880,"src":881,"variant":882},"Ubuntu Server boot menu in VirtualBox","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_1.png","slide-screenshot",[277,884,885],{"v-slot:right":279},[20,886,887,893,898],{},[23,888,889,890],{},"Choose ",[39,891,892],{},"Try or Install Ubuntu Server",[23,894,895,896],{},"Press ",[833,897,857],{},[23,899,900],{},"This starts the Ubuntu Server installer",[11,902,904,908],{"id":903,"level":265},"ubuntu-installer-language",[16,905,907],{"id":906},"step-22-language","Step 2.2: Language",[270,909,910,918],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,911,912],{"v-slot:left":279},[53,913,914],{},[283,915],{"alt":916,"src":917,"variant":882},"Ubuntu Server installer language screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_2.0.png",[277,919,920],{"v-slot:right":279},[20,921,922,925,931],{},[23,923,924],{},"Choose your preferred language",[23,926,927,930],{},[39,928,929],{},"English"," is the expected course screenshot path",[23,932,895,933,935],{},[833,934,857],{}," to continue",[11,937,939,943],{"id":938,"level":265},"ubuntu-installer-update",[16,940,942],{"id":941},"step-23-update-prompt","Step 2.3: Update Prompt",[270,944,945,953],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,946,947],{"v-slot:left":279},[53,948,949],{},[283,950],{"alt":951,"src":952,"variant":882},"Ubuntu Server installer update prompt","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_2.5.png",[277,954,955],{"v-slot:right":279},[20,956,957,967,970],{},[23,958,889,959,962],{},[39,960,961],{},"Continue without updating",[20,963,964],{},[23,965,966],{},"If I forget to update the image, it's the second option",[23,968,969],{},"Keeps the install path consistent",[23,971,972],{},"Package updates happen after Ubuntu is installed",[11,974,976,980],{"id":975,"level":265},"ubuntu-installer-keyboard",[16,977,979],{"id":978},"step-24-keyboard","Step 2.4: Keyboard",[270,981,982,990],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,983,984],{"v-slot:left":279},[53,985,986],{},[283,987],{"alt":988,"src":989,"variant":882},"Ubuntu Server installer keyboard screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_3.png",[277,991,992],{"v-slot:right":279},[20,993,994,997,1003],{},[23,995,996],{},"Keep the detected keyboard layout if it matches",[23,998,999,1000],{},"Common setting: ",[39,1001,1002],{},"English (US)",[23,1004,1005],{},"Use Identify keyboard only if typing is wrong",[11,1007,1009,1013],{"id":1008,"level":265},"ubuntu-installer-install-type",[16,1010,1012],{"id":1011},"step-25-install-type","Step 2.5: Install Type",[270,1014,1015,1023],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,1016,1017],{"v-slot:left":279},[53,1018,1019],{},[283,1020],{"alt":1021,"src":1022,"variant":882},"Ubuntu Server installer installation type screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_4.png",[277,1024,1025],{"v-slot:right":279},[20,1026,1027,1037,1040],{},[23,1028,1029,1030,1033,1034],{},"Select ",[39,1031,1032],{},"Ubuntu Server (minimized)","; don't choose full ",[39,1035,1036],{},"Ubuntu Server",[23,1038,1039],{},"Keep third-party drivers unchecked",[23,1041,1042],{},"Minimized keeps the VM lighter and aids future lessons",[11,1044,1046,1050],{"id":1045,"level":265},"ubuntu-installer-network",[16,1047,1049],{"id":1048},"step-26-network","Step 2.6: Network",[270,1051,1052,1060],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,1053,1054],{"v-slot:left":279},[53,1055,1056],{},[283,1057],{"alt":1058,"src":1059,"variant":882},"Ubuntu Server installer network configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_5.png",[277,1061,1062],{"v-slot:right":279},[20,1063,1064,1067,1073],{},[23,1065,1066],{},"DHCP address is expected",[23,1068,1069,1072],{},[39,1070,1071],{},"10.0.2.15"," is normal for VirtualBox NAT",[23,1074,1075],{},"Leave the network settings alone",[11,1077,1079,1083],{"id":1078,"level":265},"ubuntu-installer-proxy",[16,1080,1082],{"id":1081},"step-27-proxy","Step 2.7: Proxy",[270,1084,1085,1093],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,1086,1087],{"v-slot:left":279},[53,1088,1089],{},[283,1090],{"alt":1091,"src":1092,"variant":882},"Ubuntu Server installer proxy screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_6.png",[277,1094,1095],{"v-slot:right":279},[20,1096,1097,1100,1103],{},[23,1098,1099],{},"Leave proxy blank",[23,1101,1102],{},"Only fill this in if your network requires a proxy",[23,1104,1105],{},"Most student home networks do not need one",[11,1107,1109,1113],{"id":1108,"level":265},"ubuntu-installer-mirror",[16,1110,1112],{"id":1111},"step-28-mirror","Step 2.8: Mirror",[270,1114,1115,1123],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,1116,1117],{"v-slot:left":279},[53,1118,1119],{},[283,1120],{"alt":1121,"src":1122,"variant":882},"Ubuntu Server installer archive mirror screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_7.png",[277,1124,1125],{"v-slot:right":279},[20,1126,1127,1130,1133],{},[23,1128,1129],{},"Keep the default Ubuntu archive mirror",[23,1131,1132],{},"Wait for the mirror check to finish",[23,1134,1135],{},"Continue when the installer allows it",[11,1137,1139,1143],{"id":1138,"level":265},"ubuntu-installer-storage-guided",[16,1140,1142],{"id":1141},"step-29-guided-storage","Step 2.9: Guided Storage",[270,1144,1145,1153],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,1146,1147],{"v-slot:left":279},[53,1148,1149],{},[283,1150],{"alt":1151,"src":1152,"variant":882},"Ubuntu Server installer guided storage screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_8.png",[277,1154,1155],{"v-slot:right":279},[20,1156,1157,1160,1163],{},[23,1158,1159],{},"Use the entire virtual disk",[23,1161,1162],{},"LVM is optional, not needed for this course VM",[23,1164,1165],{},"Leave encryption off",[11,1167,1169,1173],{"id":1168,"level":265},"ubuntu-installer-storage-summary",[16,1170,1172],{"id":1171},"step-210-storage-summary","Step 2.10: Storage Summary",[270,1174,1175,1183],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,1176,1177],{"v-slot:left":279},[53,1178,1179],{},[283,1180],{"alt":1181,"src":1182,"variant":882},"Ubuntu Server installer storage summary screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_9.png",[277,1184,1185],{"v-slot:right":279},[20,1186,1187,1190,1193],{},[23,1188,1189],{},"Confirm the virtual disk is selected",[23,1191,1192],{},"This only affects the VM disk file",[23,1194,1195],{},"Continue when the layout looks correct",[11,1197,1199,1203],{"id":1198,"level":265},"ubuntu-installer-confirm-storage",[16,1200,1202],{"id":1201},"step-211-confirm-storage","Step 2.11: Confirm Storage",[270,1204,1205,1213],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,1206,1207],{"v-slot:left":279},[53,1208,1209],{},[283,1210],{"alt":1211,"src":1212,"variant":882},"Ubuntu Server installer destructive action confirmation","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_10.png",[277,1214,1215],{"v-slot:right":279},[20,1216,1217,1220,1223],{},[23,1218,1219],{},"Confirm the virtual disk format",[23,1221,1222],{},"This does not erase your host computer files",[23,1224,1225],{},"It formats the VM's virtual disk",[11,1227,1229,1233],{"id":1228,"level":265},"ubuntu-installer-profile",[16,1230,1232],{"id":1231},"step-212-profile","Step 2.12: Profile",[270,1234,1235,1243],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,1236,1237],{"v-slot:left":279},[53,1238,1239],{},[283,1240],{"alt":1241,"src":1242,"variant":882},"Ubuntu Server installer profile configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_11.png",[277,1244,1245],{"v-slot:right":279},[20,1246,1247,1250,1255,1258],{},[23,1248,1249],{},"Your name: your UCID or name is fine",[23,1251,1252,1253],{},"Server name: ",[39,1254,608],{},[23,1256,1257],{},"Username: your UCID",[23,1259,1260],{},"Choose a password you can type reliably (it can be simple since it's only for local work)",[11,1262,1264,1268],{"id":1263,"level":265},"ubuntu-installer-pro",[16,1265,1267],{"id":1266},"step-213-ubuntu-pro","Step 2.13: Ubuntu Pro",[270,1269,1270,1278],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,1271,1272],{"v-slot:left":279},[53,1273,1274],{},[283,1275],{"alt":1276,"src":1277,"variant":882},"Ubuntu Server installer Ubuntu Pro screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_12.png",[277,1279,1280],{"v-slot:right":279},[20,1281,1282,1287,1290],{},[23,1283,889,1284],{},[39,1285,1286],{},"Skip for now",[23,1288,1289],{},"Ubuntu Pro is not needed for the course VM",[23,1291,1292],{},"You can continue without an Ubuntu account",[11,1294,1296,1300],{"id":1295,"level":265},"ubuntu-installer-ssh",[16,1297,1299],{"id":1298},"step-214-ssh","Step 2.14: SSH",[270,1301,1302,1310],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,1303,1304],{"v-slot:left":279},[53,1305,1306],{},[283,1307],{"alt":1308,"src":1309,"variant":882},"Ubuntu Server installer SSH configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_13.png",[277,1311,1312],{"v-slot:right":279},[20,1313,1314,1320,1323],{},[23,1315,1316,1317],{},"Check ",[39,1318,1319],{},"Install OpenSSH server",[23,1321,1322],{},"Password authentication is fine for this local VM",[23,1324,1325],{},"No need to import SSH keys for this course setup",[11,1327,1329,1333],{"id":1328,"level":265},"ubuntu-installer-snaps",[16,1330,1332],{"id":1331},"step-215-featured-snaps","Step 2.15: Featured Snaps",[270,1334,1335,1343],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,1336,1337],{"v-slot:left":279},[53,1338,1339],{},[283,1340],{"alt":1341,"src":1342,"variant":882},"Ubuntu Server installer featured server snaps screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_14.png",[277,1344,1345],{"v-slot:right":279},[20,1346,1347,1350,1356],{},[23,1348,1349],{},"Leave all featured snaps unchecked",[23,1351,1352,1353],{},"Apache, PHP, and MySQL are installed later with ",[39,1354,1355],{},"apt",[23,1357,1358],{},"Continue without selecting extra packages",[11,1360,1362,1366],{"id":1361,"level":265},"ubuntu-installer-installing",[16,1363,1365],{"id":1364},"step-216-installing","Step 2.16: Installing",[270,1367,1368,1376],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,1369,1370],{"v-slot:left":279},[53,1371,1372],{},[283,1373],{"alt":1374,"src":1375,"variant":882},"Ubuntu Server installer installing system screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_15.png",[277,1377,1378,1403],{"v-slot:right":279},[20,1379,1380,1383,1386,1394,1400],{},[23,1381,1382],{},"Installation can take a while",[23,1384,1385],{},"High CPU during install is normal",[23,1387,1388,1389,1391,1392],{},"If install struggles at ",[39,1390,541],{},", recreate the VM with ",[39,1393,550],{},[23,1395,1396,1397,1399],{},"Keep the course target at ",[39,1398,541],{}," after setup if possible",[23,1401,1402],{},"Reboot once complete",[124,1404,1405],{"type":126},[53,1406,1407],{},"These target resources stay close to common cloud free-tier VMs",[53,1409,1410],{},"::\n::",[11,1412,1414,1418,1421],{"id":1413,"level":14},"step-2-networking",[16,1415,1417],{"id":1416},"virtualbox-configure-networking","VirtualBox: Configure Networking",[53,1419,1420],{},"Use one NAT adapter with port forwarding:",[20,1422,1423,1429,1438,1447,1452],{},[23,1424,1425,1426],{},"VM internet: ",[39,1427,1428],{},"NAT",[23,1430,1431,1432,1435,1436],{},"Host SSH: host ",[39,1433,1434],{},"22"," -> guest ",[39,1437,1434],{},[23,1439,1440,1441,1435,1444],{},"Host browser: host ",[39,1442,1443],{},"3000",[39,1445,1446],{},"80",[23,1448,547,1449,1451],{},[39,1450,225],{}," from the host computer",[23,1453,1454],{},"See the slides below for adapter and port-forwarding screens",[11,1456,1458,1462,1475],{"id":1457,"level":265},"adapter-settings-screen",[16,1459,1461],{"id":1460},"adapter-settings","Adapter Settings",[20,1463,1464,1467,1472],{},[23,1465,1466],{},"Adapter 1 enabled",[23,1468,1469,1470],{},"Attached to ",[39,1471,1428],{},[23,1473,1474],{},"No second adapter needed for the baseline path",[53,1476,1477],{},[283,1478],{"alt":1479,"src":1480,"variant":882},"VirtualBox Adapter 1 configured as NAT","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_adapter_1.png",[11,1482,1484,1488,1516],{"id":1483,"level":265},"port-forwarding-screen",[16,1485,1487],{"id":1486},"port-forwarding","Port Forwarding",[20,1489,1490,1498,1505],{},[23,1491,1492,1493,1495,1496],{},"SSH: host ",[39,1494,1434],{}," to guest ",[39,1497,1434],{},[23,1499,1500,1501,1495,1503],{},"Apache HTTP: host ",[39,1502,1443],{},[39,1504,1446],{},[23,1506,1507,1508,1510,1511,1495,1514],{},"If host ",[39,1509,1434],{}," is already busy, use host ",[39,1512,1513],{},"2222",[39,1515,1434],{},[53,1517,1518],{},[283,1519],{"alt":1520,"src":1521,"variant":882},"VirtualBox NAT port forwarding rules","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_adapter_1_ports.png",[11,1523,1525,1529,1532,1537,1540,1544],{"id":1524,"level":14},"step-3-connect-ssh",[16,1526,1528],{"id":1527},"step-3-connect-with-ssh","Step 3: Connect With SSH",[53,1530,1531],{},"Run from your host terminal:",[1533,1534],"code-snippet",{"language":1535,"src":1536},"bash","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-3-connect-with-ssh-01.sh",[53,1538,1539],{},"First connection prompt:",[1533,1541],{"language":1542,"src":1543},"text","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-3-connect-with-ssh-02.txt",[20,1545,1546,1553,1563,1566,1569],{},[23,1547,1548,1549,1552],{},"Replace ",[39,1550,1551],{},"your_ucid"," with your UCID",[23,1554,1555,1556,1559,1560,1562],{},"Type ",[39,1557,1558],{},"yes"," once for this course VM on ",[39,1561,225],{}," (if prompted like the example above)",[23,1564,1565],{},"Enter your Ubuntu password",[23,1567,1568],{},"After login, commands run inside Ubuntu",[23,1570,1571,1574,1575,1578],{},[39,1572,1573],{},"exit"," or ",[39,1576,1577],{},"logout"," disconnects from the VM",[11,1580,1582,1586,1589],{"id":1581,"level":14},"step-4-confirm-network",[16,1583,1585],{"id":1584},"step-4-confirm-vm-network","Step 4: Confirm VM Network",[53,1587,1588],{},"Run inside Ubuntu through SSH:",[270,1590,1593,1636],{"gap":272,"left-width":1591,"right-width":1592,"stack":275},"1.1fr","1fr",[277,1594,1595,1598,1601],{"v-slot:left":279},[53,1596,1597],{},"Network check:",[1533,1599],{"language":1535,"src":1600},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-4-confirm-vm-networ-03.sh",[20,1602,1603,1609,1615,1621,1627],{},[23,1604,1605,1608],{},[39,1606,1607],{},"ping",": confirms basic network access",[23,1610,1611,1614],{},[39,1612,1613],{},"-c 4",": stop after four replies",[23,1616,1617,1620],{},[39,1618,1619],{},"apt update",": refreshes package indexes",[23,1622,1623,1626],{},[39,1624,1625],{},"apt upgrade",": applies available package updates",[23,1628,1629,1630,1632,1633],{},"If ",[39,1631,1607],{}," is not found, run ",[39,1634,1635],{},"sudo apt install iputils-ping",[277,1637,1638,1641,1644],{"v-slot:right":279},[53,1639,1640],{},"Port-forwarding check:",[1533,1642],{"language":1535,"src":1643},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fslide-id-summary-level-2-04.sh",[20,1645,1646,1651,1654,1658],{},[23,1647,1648,1649],{},"The VM may show ",[39,1650,1071],{},[23,1652,1653],{},"That is normal for VirtualBox NAT",[23,1655,547,1656,1451],{},[39,1657,225],{},[23,1659,1660],{},"Port forwarding routes host traffic into the VM",[11,1662,1664,1668],{"id":1663,"level":14},"step-5-shared-folder",[16,1665,1667],{"id":1666},"step-5-enable-shared-folder","Step 5: Enable Shared Folder",[270,1669,1670,1704],{"gap":272,"left-width":274,"right-width":1591,"stack":275},[277,1671,1672,1675],{"v-slot:left":279},[53,1673,1674],{},"In VirtualBox:",[20,1676,1677,1680,1683,1686,1689,1692,1695,1698,1701],{},[23,1678,1679],{},"Open VM settings",[23,1681,1682],{},"Choose Shared Folders",[23,1684,1685],{},"Folder Path: your cloned course repository folder",[23,1687,1688],{},"Folder Name: a simple repo name with no spaces",[23,1690,1691],{},"Mount Point: leave blank",[23,1693,1694],{},"Read-only: off",[23,1696,1697],{},"Auto-mount: on",[23,1699,1700],{},"Make Machine-permanent: on",[23,1702,1703],{},"Make Global: off",[277,1705,1706],{"v-slot:right":279},[53,1707,1708],{},[283,1709],{"alt":1710,"src":1711,"variant":287},"VirtualBox shared folder settings with the course repo selected","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_shared_folder.png",[11,1713,1715,1719,1722,1725],{"id":1714,"level":14},"step-6-guest-additions",[16,1716,1718],{"id":1717},"step-6-install-shared-folder-support","Step 6: Install Shared Folder Support",[53,1720,1721],{},"Run inside Ubuntu:",[1533,1723],{"language":1535,"src":1724},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-6-install-shared-fo-05.sh",[20,1726,1727,1736,1742],{},[23,1728,1729,1730,1732,1733,1735],{},"Run ",[39,1731,1619],{}," and ",[39,1734,1625],{}," first only if you skipped the Step 4 updates",[23,1737,1738,1741],{},[39,1739,1740],{},"virtualbox-guest-utils",": VirtualBox shared-folder support",[23,1743,1744],{},"Reboot after the group step on the next slide",[11,1746,1748,1752,1755,1758],{"id":1747,"level":265},"step-6b-confirm-vboxsf",[16,1749,1751],{"id":1750},"step-61-check-the-shared-folder","Step 6.1: Check The Shared Folder",[53,1753,1754],{},"Reconnect with SSH, then run inside Ubuntu:",[1533,1756],{"language":1535,"src":1757},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-6-1-check-the-share-06.sh",[20,1759,1760,1766,1772],{},[23,1761,1762,1765],{},[39,1763,1764],{},"ls \u002Fmedia",": shows available mounted folders",[23,1767,1768,1771],{},[39,1769,1770],{},"ls \u002Fmedia\u002F\u003Cshared-folder>",": checks your course repo share",[23,1773,1774],{},"Permission denied is common the first time",[11,1776,1778,1782,1785,1788],{"id":1777,"level":14},"step-7-locate-share",[16,1779,1781],{"id":1780},"step-7-allow-shared-folder-access","Step 7: Allow Shared Folder Access",[53,1783,1784],{},"If the shared folder exists but says permission denied:",[1533,1786],{"language":1535,"src":1787},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-7-allow-shared-fold-07.sh",[20,1789,1790,1796,1802],{},[23,1791,1792,1795],{},[39,1793,1794],{},"vboxsf",": group allowed to read VirtualBox shared folders",[23,1797,1798,1801],{},[39,1799,1800],{},"$USER",": your Ubuntu login user for terminal access",[23,1803,1804],{},"Reboot applies the shared-folder support and new group membership",[11,1806,1808,1812,1814,1817,1834,1837],{"id":1807,"level":265},"step-7b-locate-share",[16,1809,1811],{"id":1810},"step-71-locate-the-shared-repo","Step 7.1: Locate The Shared Repo",[53,1813,1754],{},[1533,1815],{"language":1535,"src":1816},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-7-1-locate-the-shar-08.sh",[20,1818,1819,1825,1831],{},[23,1820,1821,1824],{},[39,1822,1823],{},"\u002Fmedia",": VirtualBox auto-mounted shared folders",[23,1826,1827,1830],{},[39,1828,1829],{},"\u003Cshared-folder>",": your shared course repo folder name",[23,1832,1833],{},"Use the folder that points to your repository",[53,1835,1836],{},"Expected repo folders:",[20,1838,1839,1843,1848,1853],{},[23,1840,1841],{},[39,1842,41],{},[23,1844,1845],{},[39,1846,1847],{},"lib",[23,1849,1850],{},[39,1851,1852],{},"partials",[23,1854,1855],{},[39,1856,1857],{},"sql",[11,1859,1861,1865,1882],{"id":1860,"level":265},"step-7-2-shared-folder-check",[16,1862,1864],{"id":1863},"step-72-shared-folder-check","Step 7.2: Shared Folder Check",[20,1866,1867,1870,1879],{},[23,1868,1869],{},"Edit a small file from VS Code on host",[23,1871,1729,1872,1574,1875,1878],{},[39,1873,1874],{},"ls",[39,1876,1877],{},"cat"," inside Ubuntu",[23,1880,1881],{},"Confirm Ubuntu sees the same file content",[53,1883,1884],{},"If the file does not match, stop and fix the share before Apache setup",[11,1886,1888,1892,1894,1897],{"id":1887,"level":14},"step-8-install-apache-php-mysql",[16,1889,1891],{"id":1890},"step-8-install-apache-php-and-mysql","Step 8: Install Apache, PHP, And MySQL",[53,1893,1721],{},[1533,1895],{"language":1535,"src":1896},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-8-install-apache-ph-09.sh",[20,1898,1899,1905,1911,1917,1923,1929],{},[23,1900,1901,1904],{},[39,1902,1903],{},"apache2",": web server",[23,1906,1907,1910],{},[39,1908,1909],{},"php",": PHP runtime",[23,1912,1913,1916],{},[39,1914,1915],{},"libapache2-mod-php",": lets Apache execute PHP files",[23,1918,1919,1922],{},[39,1920,1921],{},"mysql-server",": local MySQL database server",[23,1924,1925,1928],{},[39,1926,1927],{},"php-mysql",": lets PHP connect to MySQL",[23,1930,1729,1931,1732,1933,1935],{},[39,1932,1619],{},[39,1934,1625],{}," first only if they have not been run recently",[11,1937,1939,1943,1950],{"id":1938,"level":265},"optional-swap-check",[16,1940,1942],{"id":1941},"optional-add-swap-if-swap-is-off","Optional: Add Swap If Swap Is Off",[53,1944,1945,1946,1949],{},"Ubuntu usually has swap already. Only add this if ",[39,1947,1948],{},"swapon --show"," prints nothing.",[270,1951,1952,1966],{"gap":272,"left-width":1592,"right-width":1592},[277,1953,1954,1957,1960,1963],{"v-slot:left":279},[53,1955,1956],{},"Check first:",[1533,1958],{"language":1535,"src":1959},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-add-swap-if-swa-10.sh",[53,1961,1962],{},"Add a small swap file only if swap is off:",[1533,1964],{"language":1535,"src":1965},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-add-swap-if-swa-11.sh",[277,1967,1968],{"v-slot:right":279},[20,1969,1970,1973,1978,1981],{},[23,1971,1972],{},"Swap gives Ubuntu emergency disk-backed memory",[23,1974,1975,1976],{},"It helps when installs or MySQL briefly need more than ",[39,1977,541],{},[23,1979,1980],{},"It is slower than RAM, so it is not a performance upgrade",[23,1982,1983],{},"Do not run the setup again if swap already exists",[11,1985,1987,1991,1997],{"id":1986,"level":265},"optional-apache-low-memory",[16,1988,1990],{"id":1989},"optional-limit-apache-memory-use","Optional: Limit Apache Memory Use",[53,1992,1993,1994,1996],{},"Use this if the ",[39,1995,541],{}," VM feels unstable or Apache starts too many PHP workers.",[270,1998,1999,2012],{"gap":272,"left-width":1592,"right-width":1592},[277,2000,2001,2004,2009],{"v-slot:left":279},[53,2002,2003],{},"Edit Apache prefork settings in:",[53,2005,2006],{},[39,2007,2008],{},"\u002Fetc\u002Fapache2\u002Fmods-available\u002Fmpm_prefork.conf",[1533,2010],{"language":1535,"src":2011},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-apache-me-12.sh",[277,2013,2014,2017,2021],{"v-slot:right":279},[53,2015,2016],{},"Change the existing values to:",[1533,2018],{"language":2019,"src":2020},"apache","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-apache-me-13.txt",[20,2022,2023,2029,2032,2039],{},[23,2024,2025,2026],{},"Edit the existing lines inside ",[39,2027,2028],{},"\u003CIfModule mpm_prefork_module>",[23,2030,2031],{},"If a line is missing, add it inside that same block",[23,2033,2034,2035,2038],{},"Do not paste a second ",[39,2036,2037],{},"\u003CIfModule>"," block",[23,2040,2041],{},"Restart Apache after config changes",[11,2043,2045,2049,2055],{"id":2044,"level":265},"optional-mysql-low-memory",[16,2046,2048],{"id":2047},"optional-limit-mysql-memory-use","Optional: Limit MySQL Memory Use",[53,2050,2051,2052,2054],{},"Use this only if MySQL struggles on the ",[39,2053,541],{}," VM.",[270,2056,2057,2070],{"gap":272,"left-width":1592,"right-width":1592},[277,2058,2059,2062,2067],{"v-slot:left":279},[53,2060,2061],{},"Edit MySQL server settings in:",[53,2063,2064],{},[39,2065,2066],{},"\u002Fetc\u002Fmysql\u002Fmysql.conf.d\u002Fmysqld.cnf",[1533,2068],{"language":1535,"src":2069},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-mysql-mem-14.sh",[277,2071,2072,2079,2083],{"v-slot:right":279},[53,2073,2074,2075,2078],{},"Add or edit these under ",[39,2076,2077],{},"[mysqld]",":",[1533,2080],{"language":2081,"src":2082},"ini","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-mysql-mem-15.txt",[20,2084,2085,2091,2096,2099],{},[23,2086,2087,2088,2090],{},"Keep these under the existing ",[39,2089,2077],{}," heading",[23,2092,2093,2094,2090],{},"Do not create a second ",[39,2095,2077],{},[23,2097,2098],{},"If either setting already exists, edit it instead of adding a duplicate",[23,2100,2101],{},"Restart MySQL after config changes",[11,2103,2105,2108,2111,2114],{"id":2104,"level":265},"low-memory-diagnostics",[16,2106,2107],{"id":2104},"Low Memory Diagnostics",[53,2109,2110],{},"Run these after the minor tuning checks:",[1533,2112],{"language":1535,"src":2113},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Flow-memory-diagnostics-10.sh",[20,2115,2116,2122,2127,2133,2140],{},[23,2117,2118,2121],{},[39,2119,2120],{},"free -h",": shows RAM and swap",[23,2123,2124,2126],{},[39,2125,1948],{},": confirms whether swap is active",[23,2128,2129,2132],{},[39,2130,2131],{},"systemctl status",": checks whether Apache and MySQL are running",[23,2134,2135,2136,2139],{},"No output from the ",[39,2137,2138],{},"grep"," line is usually good",[23,2141,2142],{},"Do not tune randomly; change one setting, restart, then retest",[11,2144,2146,2150,2152,2155,2158,2161],{"id":2145,"level":14},"step-9-create-local-mysql-db",[16,2147,2149],{"id":2148},"step-9-create-a-local-mysql-database","Step 9: Create A Local MySQL Database",[53,2151,1721],{},[1533,2153],{"language":1535,"src":2154},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-9-create-a-local-my-11.sh",[53,2156,2157],{},"Then run in the MySQL prompt:",[1533,2159],{"language":1857,"src":2160},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-9-create-a-local-my-12.sql",[20,2162,2163,2167,2170],{},[23,2164,1548,2165,1552],{},[39,2166,1551],{},[23,2168,2169],{},"Database name and username should match your UCID",[23,2171,2172],{},"Password is local-only unless your instructor says otherwise",[11,2174,2176,2179,2182,2197,2200,2207],{"id":2175,"level":14},"local-vs-remote-database",[16,2177,2178],{"id":2175},"Local Vs Remote Database",[53,2180,2181],{},"This MySQL database is only for local testing:",[20,2183,2184,2189,2192,2194],{},[23,2185,2186,2187],{},"Host: ",[39,2188,225],{},[23,2190,2191],{},"Database: your UCID",[23,2193,1257],{},[23,2195,2196],{},"Password: your local password",[53,2198,2199],{},"Render uses the instructor-provided remote database connection string",[53,2201,2202,2203],{},"Get that string from ",[146,2204,2205],{"href":2205,"rel":2206},"https:\u002F\u002Fcourses.ethereallab.app\u002Fdatabase",[150],[53,2208,2209],{},"After this lesson, you may optionally point local code at that remote database for extra testing",[11,2211,2213,2217,2219,2222,2225,2228,2231],{"id":2212,"level":14},"step-10-confirm-local-mysql",[16,2214,2216],{"id":2215},"step-10-confirm-local-mysql-login","Step 10: Confirm Local MySQL Login",[53,2218,1721],{},[1533,2220],{"language":1535,"src":2221},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-10-confirm-local-my-13.sh",[53,2223,2224],{},"Then run:",[1533,2226],{"language":1857,"src":2227},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-10-confirm-local-my-14.sql",[53,2229,2230],{},"Expected:",[20,2232,2233,2239],{},[23,2234,2235,2238],{},[39,2236,2237],{},"SELECT DATABASE()"," returns your UCID",[23,2240,2241,2244],{},[39,2242,2243],{},"SHOW TABLES"," is empty or shows starter tables later",[11,2246,2248,2254,2257,2260,2263],{"id":2247,"level":14},"step-11-documentroot",[16,2249,2251,2252],{"id":2250},"step-11-point-apache-at-public_html","Step 11: Point Apache At ",[39,2253,41],{},[53,2255,2256],{},"Apache should serve:",[1533,2258],{"language":1542,"src":2259},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-11-point-apache-at--15.txt",[53,2261,2262],{},"Do not serve the whole repo",[20,2264,2265,2276],{},[23,2266,2267,2269,2270,2272,2273,2275],{},[39,2268,1847],{},", ",[39,2271,1852],{},", and ",[39,2274,1857],{}," stay outside the web root",[23,2277,2278,2280],{},[39,2279,41],{}," is the browser-facing folder",[11,2282,2284,2288,2291,2296,2299,2304,2307,2310],{"id":2283,"level":265},"apache-site-config",[16,2285,2287],{"id":2286},"step-111-apache-site-config","Step 11.1: Apache Site Config",[53,2289,2290],{},"Create or edit this Apache site config file inside Ubuntu:",[53,2292,2293],{},[39,2294,2295],{},"\u002Fetc\u002Fapache2\u002Fsites-available\u002Fit202.conf",[53,2297,2298],{},"Run:",[53,2300,2301],{},[39,2302,2303],{},"sudo nano \u002Fetc\u002Fapache2\u002Fsites-available\u002Fit202.conf",[53,2305,2306],{},"Add this content to that file:",[1533,2308],{"language":2019,"src":2309},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-11-1-apache-site-co-16.txt",[20,2311,2312,2317,2323,2328],{},[23,2313,1548,2314,2316],{},[39,2315,1829],{}," with the actual shared folder name",[23,2318,2319,2320],{},"Save the file as ",[39,2321,2322],{},"it202.conf",[23,2324,2325,2326],{},"Apache listens on guest port ",[39,2327,1446],{},[23,2329,2330,2331],{},"Host browser reaches it through ",[39,2332,77],{},[11,2334,2336,2340,2342,2345],{"id":2335,"level":265},"enable-site",[16,2337,2339],{"id":2338},"step-112-enable-the-site","Step 11.2: Enable The Site",[53,2341,1721],{},[1533,2343],{"language":1535,"src":2344},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-11-2-enable-the-sit-17.sh",[20,2346,2347,2353,2359,2365,2374,2380],{},[23,2348,2349,2352],{},[39,2350,2351],{},"a2ensite",": enable a site config",[23,2354,2355,2358],{},[39,2356,2357],{},"a2dissite",": disable a site config",[23,2360,2361,2364],{},[39,2362,2363],{},"www-data",": Apache's user for browser requests",[23,2366,2367,2368,2370,2371,2373],{},"Adding ",[39,2369,2363],{}," to ",[39,2372,1794],{}," lets Apache read the shared folder",[23,2375,2376,2379],{},[39,2377,2378],{},"configtest",": check syntax before reload",[23,2381,2382,2385],{},[39,2383,2384],{},"restart",": applies the Apache user group change",[11,2387,2389,2393,2396,2399,2402],{"id":2388,"level":14},"step-12-php-check-page",[16,2390,2392],{"id":2391},"step-12-create-a-php-check-page","Step 12: Create A PHP Check Page",[53,2394,2395],{},"Create this file on the host:",[1533,2397],{"language":1542,"src":2398},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-12-create-a-php-che-18.txt",[53,2400,2401],{},"Example content:",[1533,2403],{"language":1909,"src":2404},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-12-create-a-php-che-19.php",[11,2406,2408,2411,2414,2417,2419],{"id":2407,"level":14},"final-browser-check",[16,2409,2410],{"id":2407},"Final Browser Check",[53,2412,2413],{},"Open from host browser:",[1533,2415],{"language":1542,"src":2416},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Ffinal-browser-check-20.txt",[53,2418,2230],{},[20,2420,2421,2424,2427,2430],{},[23,2422,2423],{},"Message appears",[23,2425,2426],{},"Time appears",[23,2428,2429],{},"PHP code is not shown as raw text",[23,2431,2432],{},"Editing the file on host changes output after refresh",[11,2434,2436,2439],{"id":2435,"level":14},"common-problems",[16,2437,2438],{"id":2435},"Common Problems",[20,2440,2441,2444,2447,2452,2455,2468,2478],{},[23,2442,2443],{},"Browser timeout: missing or wrong port-forwarding rule",[23,2445,2446],{},"Connection refused: Apache not running",[23,2448,2449,2450],{},"No internet in VM: check Adapter 1 is still ",[39,2451,1428],{},[23,2453,2454],{},"Shared folder missing: check Auto-mount and guest utilities",[23,2456,2457,2458,2461,2462,2464,2465,2467],{},"Browser shows ",[39,2459,2460],{},"403 Forbidden",": confirm ",[39,2463,2363],{}," is in ",[39,2466,1794],{},", then restart Apache or reboot",[23,2469,2470,2471,2474,2475,2477],{},"Permission denied on ",[39,2472,2473],{},"\u002Fmedia\u002Fsf_...",": confirm your Ubuntu user is in ",[39,2476,1794],{}," and reboot",[23,2479,2480],{},"Raw PHP code: PHP module not running through Apache",[11,2482,2484,2487,2490],{"id":2483,"level":14},"recovery-routine",[16,2485,2486],{"id":2483},"Recovery Routine",[53,2488,2489],{},"Check in this order:",[2491,2492,2493,2496,2502,2508,2513,2521,2528,2534,2539,2548],"ol",{},[23,2494,2495],{},"VM is running",[23,2497,2498,2501],{},[39,2499,2500],{},"ping github.com"," works inside Ubuntu",[23,2503,2504,2507],{},[39,2505,2506],{},"ssh username@localhost"," works from host",[23,2509,2510,2512],{},[39,2511,1770],{}," shows the shared repo",[23,2514,2515,2518,2519],{},[39,2516,2517],{},"groups"," includes ",[39,2520,1794],{},[23,2522,2523,2518,2526],{},[39,2524,2525],{},"id www-data",[39,2527,1794],{},[23,2529,2530,2533],{},[39,2531,2532],{},"sudo systemctl status apache2"," is active",[23,2535,2536,2533],{},[39,2537,2538],{},"sudo systemctl status mysql",[23,2540,2541,2544,2545],{},[39,2542,2543],{},"sudo apache2ctl configtest"," says ",[39,2546,2547],{},"Syntax OK",[23,2549,2550,2553],{},[39,2551,2552],{},"http:\u002F\u002Flocalhost:3000\u002Fsystem\u002Fvm-check.php"," loads from the host browser",[11,2555,2557,2560],{"id":2556,"level":14},"key-terms-and-further-learning",[16,2558,2559],{"id":2556},"Key Terms And Further Learning",[270,2561,2562,2607],{"gap":272,"left-width":1592,"right-width":1592},[277,2563,2564,2569,2576,2585,2590,2596,2602],{"v-slot:left":279},[2565,2566,2568],"h3",{"id":2567},"key-terms","Key Terms",[53,2570,2571,2575],{},[2572,2573,2574],"strong",{},"VM"," - separate computer running inside your host computer",[53,2577,2578,2581,2582,2584],{},[2572,2579,2580],{},"Port forwarding"," - host ",[39,2583,225],{}," traffic routed into the VM",[53,2586,2587,2589],{},[2572,2588,1794],{}," - VirtualBox shared-folder permission group",[53,2591,2592,2595],{},[2572,2593,2594],{},"Guest utilities"," - VirtualBox tools that help shared folders work inside Ubuntu",[53,2597,2598,2601],{},[2572,2599,2600],{},"DocumentRoot"," - folder Apache serves to browsers",[53,2603,2604,2606],{},[2572,2605,1428],{}," - VM network mode that gives the VM outbound internet access",[277,2608,2609,2613],{"v-slot:right":279},[2565,2610,2612],{"id":2611},"further-learning","Further Learning",[20,2614,2615,2621,2628,2635,2642,2649,2655],{},[23,2616,2617],{},[146,2618,2620],{"href":148,"rel":2619},[150],"VirtualBox Downloads",[23,2622,2623],{},[146,2624,2627],{"href":2625,"rel":2626},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002FIntroduction.html",[150],"VirtualBox Manual: Host And Guest Combinations",[23,2629,2630],{},[146,2631,2634],{"href":2632,"rel":2633},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Finstallation.html",[150],"VirtualBox Manual: Installation",[23,2636,2637],{},[146,2638,2641],{"href":2639,"rel":2640},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Fsharedfolders.html",[150],"VirtualBox Manual: Shared Folders",[23,2643,2644],{},[146,2645,2648],{"href":2646,"rel":2647},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Fnetworkingdetails.html#network_nat_service",[150],"VirtualBox Manual: NAT Port Forwarding",[23,2650,2651],{},[146,2652,2654],{"href":167,"rel":2653},[150],"Ubuntu Server: Installer",[23,2656,2657],{},[146,2658,2661],{"href":2659,"rel":2660},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Fserver\u002Fhow-to\u002Fsecurity\u002Fopenssh-server\u002F",[150],"Ubuntu Server: OpenSSH Server",[11,2663,2665,2668,2671],{"id":2664,"level":14},"summary",[16,2666,2667],{"id":2664},"Summary",[53,2669,2670],{},"Before leaving this presentation, confirm you can:",[20,2672,2673,2676,2679,2682,2685,2690],{},[23,2674,2675],{},"Pick the correct Ubuntu ISO for your host CPU",[23,2677,2678],{},"Configure NAT port forwarding",[23,2680,2681],{},"Connect to Ubuntu with SSH",[23,2683,2684],{},"Find the VirtualBox shared repo",[23,2686,2687,2688],{},"Configure Apache to serve ",[39,2689,41],{},[23,2691,2692],{},"Create a local MySQL database and user named after your UCID",{"title":279,"searchDepth":2694,"depth":2694,"links":2695},2,[2696,2697,2698,2699,2700,2701,2702,2703,2704,2705,2706,2707,2708,2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720,2721,2722,2723,2724,2725,2726,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2737,2738,2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,2751,2752,2754,2755,2756,2757,2758,2759,2760,2761],{"id":18,"depth":2694,"text":5},{"id":48,"depth":2694,"text":51},{"id":94,"depth":2694,"text":97},{"id":132,"depth":2694,"text":135},{"id":205,"depth":2694,"text":208},{"id":240,"depth":2694,"text":241},{"id":264,"depth":2694,"text":268},{"id":306,"depth":2694,"text":309},{"id":332,"depth":2694,"text":335},{"id":361,"depth":2694,"text":364},{"id":393,"depth":2694,"text":394},{"id":417,"depth":2694,"text":420},{"id":448,"depth":2694,"text":451},{"id":480,"depth":2694,"text":481},{"id":518,"depth":2694,"text":519},{"id":582,"depth":2694,"text":585},{"id":617,"depth":2694,"text":620},{"id":664,"depth":2694,"text":667},{"id":707,"depth":2694,"text":710},{"id":751,"depth":2694,"text":754},{"id":803,"depth":2694,"text":804},{"id":867,"depth":2694,"text":868},{"id":906,"depth":2694,"text":907},{"id":941,"depth":2694,"text":942},{"id":978,"depth":2694,"text":979},{"id":1011,"depth":2694,"text":1012},{"id":1048,"depth":2694,"text":1049},{"id":1081,"depth":2694,"text":1082},{"id":1111,"depth":2694,"text":1112},{"id":1141,"depth":2694,"text":1142},{"id":1171,"depth":2694,"text":1172},{"id":1201,"depth":2694,"text":1202},{"id":1231,"depth":2694,"text":1232},{"id":1266,"depth":2694,"text":1267},{"id":1298,"depth":2694,"text":1299},{"id":1331,"depth":2694,"text":1332},{"id":1364,"depth":2694,"text":1365},{"id":1416,"depth":2694,"text":1417},{"id":1460,"depth":2694,"text":1461},{"id":1486,"depth":2694,"text":1487},{"id":1527,"depth":2694,"text":1528},{"id":1584,"depth":2694,"text":1585},{"id":1666,"depth":2694,"text":1667},{"id":1717,"depth":2694,"text":1718},{"id":1750,"depth":2694,"text":1751},{"id":1780,"depth":2694,"text":1781},{"id":1810,"depth":2694,"text":1811},{"id":1863,"depth":2694,"text":1864},{"id":1890,"depth":2694,"text":1891},{"id":1941,"depth":2694,"text":1942},{"id":1989,"depth":2694,"text":1990},{"id":2047,"depth":2694,"text":2048},{"id":2104,"depth":2694,"text":2107},{"id":2148,"depth":2694,"text":2149},{"id":2175,"depth":2694,"text":2178},{"id":2215,"depth":2694,"text":2216},{"id":2250,"depth":2694,"text":2753},"Step 11: Point Apache At public_html",{"id":2286,"depth":2694,"text":2287},{"id":2338,"depth":2694,"text":2339},{"id":2391,"depth":2694,"text":2392},{"id":2407,"depth":2694,"text":2410},{"id":2435,"depth":2694,"text":2438},{"id":2483,"depth":2694,"text":2486},{"id":2556,"depth":2694,"text":2559},{"id":2664,"depth":2694,"text":2667},"presentation","Internet Applications","Build the local Ubuntu VM path with VirtualBox, Apache, PHP, MySQL, SSH, and shared folders.","Face-to-face class of about 40 students; includes VirtualBox install differences, CPU\u002FISO selection, networking, SSH, shared folders, Apache\u002FPHP\u002FMySQL, browser checks, and beginner troubleshooting.","25","95","120",{},true,"90","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox",false,{"title":5,"description":2764},"published","internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox",[2778,2779,2019,2780,2781],"virtualbox","ubuntu","mysql","vm","1:06:16","ArTDIgihfd4","https:\u002F\u002Fyoutu.be\u002FArTDIgihfd4","IT202 VirtualBox and VM Setup","CNlzYvIiYNPSzbQ6tvCdcnJLlvvGSGmurOGWR_mSnms",null,[],[2790,3286,4344,5222,6313,7249,8034,9095,9820,10644],{"id":2791,"title":2792,"audience":6,"body":2793,"contentType":2762,"course":2763,"description":3266,"estimateBasis":3267,"estimatedDiscussionMinutes":3268,"estimatedLiveMinutes":3269,"estimatedTotalMinutes":3270,"extension":871,"meta":3271,"module":569,"navigation":2770,"order":3272,"path":3273,"promptAssist":2773,"seo":3274,"status":2775,"stem":3275,"tags":3276,"videoDuration":3281,"videoId":3282,"videoLink":3283,"videoTitle":3284,"week":569,"__hash__":3285},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord.md","Learn Courses Platform And Discord",{"type":8,"value":2794,"toc":3250},[2795,2829,2869,2913,2961,3009,3042,3104,3145,3195,3224],[11,2796,2798,2802,2816],{"id":2797,"level":14},"learn-courses-flow",[16,2799,2801],{"id":2800},"what-is-the-learn-courses-platform","What is the Learn Courses Platform",[20,2803,2804,2807,2810,2813],{},[23,2805,2806],{},"This is a platform I've built over the years to aid assignment submissions and course utilities",[23,2808,2809],{},"It provides objective-based worksheets to fill in images, urls, and open responses to document assignment evidence",[23,2811,2812],{},"The goal is to keep tasks clear and objective for students and grading",[23,2814,2815],{},"Also includes a few other utilities for courses (such as joining the Discord server)",[53,2817,2818,2819,2823,2824,2828],{},"NOTE: Summer 2026 the previous Learn Platform (",[146,2820,2821],{"href":2821,"rel":2822},"https:\u002F\u002Flearn.ethereallab.app",[150],") has been replaced by Learn Courses Platform (",[146,2825,2826],{"href":2826,"rel":2827},"https:\u002F\u002Fcourses.ethereallab.app",[150],"). The deprecated site is still available as a backup but all activities\u002Fcontent is being migrated to the new version",[11,2830,2832,2835,2838,2866],{"id":2831,"level":14},"learn-courses-title",[16,2833,2792],{"id":2834},"learn-courses-platform-and-discord",[53,2836,2837],{},"How to join:",[20,2839,2840,2846,2854,2857,2860,2863],{},[23,2841,2842,2843],{},"Visit the platform ",[146,2844,2826],{"href":2826,"rel":2845},[150],[23,2847,2848,2849],{},"Sign in with your NJIT email\n",[20,2850,2851],{},[23,2852,2853],{},"If you're in the Canvas course, you should automatically get synced to this platform",[23,2855,2856],{},"Visit your Profile page",[23,2858,2859],{},"Associate your Discord account",[23,2861,2862],{},"Join the course Discord server",[23,2864,2865],{},"Verify that your course channels appear on Discord",[53,2867,2868],{},"You can follow the steps on the below slides for guidance",[11,2870,2872,2875],{"id":2871,"level":265},"visit-learn-courses",[16,2873,2874],{"id":2871},"Visit Learn Courses",[270,2876,2877,2905],{"gap":272,"left-width":1592,"right-width":1592},[277,2878,2879,2882,2887],{"v-slot:left":279},[53,2880,2881],{},"Go to:",[53,2883,2884],{},[146,2885,2826],{"href":2826,"rel":2886},[150],[20,2888,2889,2896,2899,2902],{},[23,2890,2891,2892,2895],{},"Click the ",[2572,2893,2894],{},"Login"," button",[23,2897,2898],{},"Use your NJIT email",[23,2900,2901],{},"Only NJIT accounts are allowed",[23,2903,2904],{},"If the browser tries a personal Chrome profile, log out of that account or switch profiles",[277,2906,2907],{"v-slot:right":279},[53,2908,2909],{},[283,2910],{"alt":2911,"src":2912,"variant":287},"Learn Courses logged-out home page with the Login button visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fhome-loggedout-login-button.png",[11,2914,2916,2919],{"id":2915,"level":265},"associate-discord-name",[16,2917,2918],{"id":2915},"Associate Discord Name",[270,2920,2921,2945],{"gap":272,"left-width":1592,"right-width":1592},[277,2922,2923,2926,2942],{"v-slot:left":279},[53,2924,2925],{},"On Learn Courses:",[2491,2927,2928,2931,2936,2939],{},[23,2929,2930],{},"Open your Profile",[23,2932,774,2933],{},[2572,2934,2935],{},"Refresh Discord Username",[23,2937,2938],{},"Authorize the Discord prompt",[23,2940,2941],{},"After the success message appears, save your profile",[53,2943,2944],{},"If you are not sure where you are, use the Home icon in the top left to return to the dashboard.",[277,2946,2947,2954],{"v-slot:right":279},[53,2948,2949],{},[283,2950],{"alt":2951,"src":2952,"variant":287,"max-height":2953},"Learn Courses dashboard sidebar with Profile and course links visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdashboard-sidebar-profile-links.png","13rem",[53,2955,2956],{},[283,2957],{"alt":2958,"src":2959,"variant":287,"max-height":2960},"Learn Courses profile page with Discord connection controls visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fprofile-page.png","16rem",[11,2962,2964,2967],{"id":2963,"level":265},"authorize-discord",[16,2965,2966],{"id":2963},"Authorize Discord",[270,2968,2969,2993],{"gap":272,"left-width":1592,"right-width":1592},[277,2970,2971,2974],{"v-slot:left":279},[53,2972,2973],{},"Discord will ask whether Learn Courses can access your Discord account.",[20,2975,2976,2979,2984,2987,2990],{},[23,2977,2978],{},"Confirm you are signed in to the correct Discord account",[23,2980,774,2981],{},[2572,2982,2983],{},"Authorize",[23,2985,2986],{},"Return to Learn Courses",[23,2988,2989],{},"Look for the success message",[23,2991,2992],{},"Save the profile change",[277,2994,2995,3002],{"v-slot:right":279},[53,2996,2997],{},[283,2998],{"alt":2999,"src":3000,"variant":287,"max-height":3001},"Discord authorization prompt for Learn Courses","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdiscord-auth.png","25rem",[53,3003,3004],{},[283,3005],{"alt":3006,"src":3007,"variant":287,"max-height":3008},"Learn Courses success message after connecting Discord","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdiscord-connected-success.png","7rem",[11,3010,3012,3015,3018,3024,3031],{"id":3011,"level":265},"join-the-channel",[16,3013,3014],{"id":3011},"Join The Channel",[53,3016,3017],{},"Use the Discord link provided on Canvas, or use:",[53,3019,3020],{},[146,3021,3022],{"href":3022,"rel":3023},"https:\u002F\u002Fdiscord.com\u002Finvite\u002FYEHcm44wzg",[150],[53,3025,3026,3027,3030],{},"This should send you to the ",[39,3028,3029],{},"access-channel"," channel.",[20,3032,3033,3036,3039],{},[23,3034,3035],{},"Other channels are protected by a bot",[23,3037,3038],{},"Messages may be blocked until your name and role are set",[23,3040,3041],{},"You'll have temporary access until a role is applied so if you leave before completing the steps you'll have to revisit the invite link",[11,3043,3045,3048],{"id":3044,"level":14},"verify-with-quackbot",[16,3046,3047],{"id":3044},"Verify With QuackBot",[270,3049,3050,3095],{"gap":272,"left-width":1592,"right-width":1592},[277,3051,3052,3064,3070,3075,3078,3092],{"v-slot:left":279},[20,3053,3054,3057],{},[23,3055,3056],{},"A summer 2026 change was to have the bot attempt to auto-detect new members and apply roles automatically",[23,3058,3059,3060,3063],{},"If you don't see the proper semester category (i.e., ",[39,3061,3062],{},"summer-2026",") or the expected channels you can do the below action",[53,3065,3066,3067,3069],{},"In ",[39,3068,3029],{},", enter:",[53,3071,3072],{},[39,3073,3074],{},"@QuackBot",[53,3076,3077],{},"QuackBot will:",[20,3079,3080,3083,3086,3089],{},[23,3081,3082],{},"Verify your account",[23,3084,3085],{},"Pull in your name and section",[23,3087,3088],{},"Apply your class role",[23,3090,3091],{},"Update your server nickname",[53,3093,3094],{},"This does not change your real Discord username.",[277,3096,3097],{"v-slot:right":279},[53,3098,3099],{},[283,3100],{"alt":3101,"src":3102,"variant":287,"max-height":3103},"QuackBot response showing the student already has a course role","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fquackbot-role-response.png","8rem",[11,3105,3107,3111,3114,3125,3129],{"id":3106,"level":14},"welcome-and-potential-issues",[16,3108,3110],{"id":3109},"welcome","Welcome",[53,3112,3113],{},"If the previous steps worked, you should see a new semester category in the Discord sidebar.",[20,3115,3116,3119,3122],{},[23,3117,3118],{},"It should appear after the general channels",[23,3120,3121],{},"It should include one or more channels for your active courses",[23,3123,3124],{},"Use the correct course channel for class questions and discussion",[2565,3126,3128],{"id":3127},"potential-issues","Potential Issues",[20,3130,3131,3134],{},[23,3132,3133],{},"If you recently joined the class, your UCID may still need to be added to Learn Courses",[23,3135,3136,3137,3140],{},"If there is an issue, email the instructor or DM ",[39,3138,3139],{},"MattToegel",[20,3141,3142],{},[23,3143,3144],{},"Some Discord privacy settings may require a friend request before DMs work",[11,3146,3148,3151],{"id":3147,"level":14},"general-conduct",[16,3149,3150],{"id":3147},"General Conduct",[20,3152,3153,3156,3159,3170,3173,3181,3189,3192],{},[23,3154,3155],{},"Use class-related channels for questions and discussion",[23,3157,3158],{},"Ask general course questions in the channel instead of DM when possible",[23,3160,3161,3162],{},"Do not post screenshots of in-progress assignment solutions\n",[20,3163,3164,3167],{},[23,3165,3166],{},"This would be more ideal for a DM",[23,3168,3169],{},"If you see posted solution-like items don't assume they're correct",[23,3171,3172],{},"General unrelated code is okay when it supports a discussion (like content from a presentation or reading)",[23,3174,3175,3176],{},"If the instructor needs to see assignment code, they may ask you to DM the screenshot\n",[20,3177,3178],{},[23,3179,3180],{},"Since repositories should be set to private; repo links are fine to post in the class channel since other students should not have access to them",[23,3182,3183,3184],{},"Keep off-topic items out of class channels\n",[20,3185,3186],{},[23,3187,3188],{},"There are plenty of categorized channels to use and I can always make more",[23,3190,3191],{},"Helping classmates understand topics is encouraged just be mindful not to spoon-feed",[23,3193,3194],{},"Sharing direct solutions goes against the Academic Integrity Policy",[11,3196,3198,3201,3204],{"id":3197,"level":14},"quick-check",[16,3199,3200],{"id":3197},"Quick Check",[53,3202,3203],{},"Before continuing, confirm:",[20,3205,3206,3209,3212,3215,3218,3221],{},[23,3207,3208],{},"You can sign in to Learn Courses with your NJIT email",[23,3210,3211],{},"Your profile is saved",[23,3213,3214],{},"Discord is associated with your Learn Courses profile",[23,3216,3217],{},"You joined the Discord server",[23,3219,3220],{},"QuackBot applied your course role",[23,3222,3223],{},"You can see the correct course channel",[11,3225,3226,3228],{"id":2664,"level":14},[16,3227,2667],{"id":2664},[20,3229,3230,3233,3241,3244,3247],{},[23,3231,3232],{},"Learn Courses supports course tools and course-specific setup",[23,3234,3235,3236],{},"Canvas remains the official assignment, grade, and course hub\n",[20,3237,3238],{},[23,3239,3240],{},"All necessary items will be linked on Canvas",[23,3242,3243],{},"Discord is the preferred quick communication channel",[23,3245,3246],{},"QuackBot connects your Discord account to the correct course role",[23,3248,3249],{},"Good course communication keeps help requests specific and protects private information",{"title":279,"searchDepth":2694,"depth":2694,"links":3251},[3252,3253,3254,3255,3256,3257,3258,3259,3263,3264,3265],{"id":2800,"depth":2694,"text":2801},{"id":2834,"depth":2694,"text":2792},{"id":2871,"depth":2694,"text":2874},{"id":2915,"depth":2694,"text":2918},{"id":2963,"depth":2694,"text":2966},{"id":3011,"depth":2694,"text":3014},{"id":3044,"depth":2694,"text":3047},{"id":3109,"depth":2694,"text":3110,"children":3260},[3261],{"id":3127,"depth":3262,"text":3128},3,{"id":3147,"depth":2694,"text":3150},{"id":3197,"depth":2694,"text":3200},{"id":2664,"depth":2694,"text":2667},"Set up Learn Courses Platform and Discord before starting terminal, Git, and local server work.","Face-to-face class of about 40 students; includes account sign-in, Discord association, QuackBot role setup, and communication expectations.","10","20","30",{},"0","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord",{"title":2792,"description":3266},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord",[3277,3278,3279,3280],"course-tools","learn-courses","discord","setup","11:16","ScmHyEF1sA0","https:\u002F\u002Fyoutu.be\u002FScmHyEF1sA0","Joining Learn Platform and Discord Server","tEFV7lUabcy7whz7FSHEjPXSirrd3ginqQq4O4AkW9o",{"id":3287,"title":3288,"audience":6,"body":3289,"contentType":2762,"course":2763,"description":4328,"estimateBasis":4329,"estimatedDiscussionMinutes":3268,"estimatedLiveMinutes":4330,"estimatedTotalMinutes":4331,"extension":871,"meta":4332,"module":569,"navigation":2770,"order":3268,"path":4333,"promptAssist":2773,"seo":4334,"status":2775,"stem":4335,"tags":4336,"videoDuration":4340,"videoId":4341,"videoLink":4342,"videoTitle":3288,"week":569,"__hash__":4343},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands.md","Basic CLI Commands",{"type":8,"value":3290,"toc":4294},[3291,3349,3384,3414,3476,3543,3592,3618,3635,3673,3701,3722,3757,3778,3850,3873,3917,3978,4028,4056,4076,4105,4145,4175,4185,4248],[11,3292,3294,3298],{"id":3293,"level":14},"why-cli-first",[16,3295,3297],{"id":3296},"why-cli-comes-first","Why CLI Comes First",[20,3299,3300,3308,3316,3330,3338],{},[23,3301,3302,3303],{},"Common language for setup and developer tools\n",[20,3304,3305],{},[23,3306,3307],{},"Git, servers, package installs, deployment logs",[23,3309,3310,3311],{},"Works when there is no full desktop\n",[20,3312,3313],{},[23,3314,3315],{},"SSH, Ubuntu Server, minimal system access",[23,3317,3318,3319],{},"Direct check of what the computer sees\n",[20,3320,3321,3324,3327],{},[23,3322,3323],{},"Current folder",[23,3325,3326],{},"Files and permissions",[23,3328,3329],{},"Command output",[23,3331,3332,3333],{},"Repeatable steps beat guessing through menus\n",[20,3334,3335],{},[23,3336,3337],{},"Run a command, read output, adjust",[23,3339,3340,3341],{},"Location still matters\n",[20,3342,3343,3346],{},[23,3344,3345],{},"Wrong folder can make correct commands fail",[23,3347,3348],{},"Or create files in the wrong place",[11,3350,3352,3355,3358],{"id":3351,"level":14},"goal",[16,3353,3354],{"id":3351},"Goal",[53,3356,3357],{},"Build the command-line habits that make setup work predictable:",[20,3359,3360,3363,3366,3378,3381],{},[23,3361,3362],{},"Know what folder the terminal is using",[23,3364,3365],{},"Read file and folder lists before moving",[23,3367,3368,3369,2269,3372,2272,3375],{},"Recognize common flags like ",[39,3370,3371],{},"-a",[39,3373,3374],{},"-r",[39,3376,3377],{},"-l",[23,3379,3380],{},"Make small file changes and verify them",[23,3382,3383],{},"Stop safely when output does not match the lesson",[11,3385,3386,3388,3391,3411],{"id":132,"level":14},[16,3387,135],{"id":132},[53,3389,3390],{},"Run these commands on your host computer",[20,3392,3393,3405,3408],{},[23,3394,3395,3396],{},"Windows: Git Bash",[20,3397,3398],{},[23,3399,3400,3401],{},"Need Git Bash now? Use the Windows install slide in the next presentation:\n",[146,3402,3404],{"href":3403},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fview\u002Fslides#step-1-install-git-on-windows","Install Git On Windows",[23,3406,3407],{},"Apple macOS: Terminal",[23,3409,3410],{},"Linux: Terminal",[53,3412,3413],{},"Use one terminal window for the whole practice so your location is easy to track",[11,3415,3417,3421],{"id":3416,"level":14},"working-directory",[16,3418,3420],{"id":3419},"the-main-idea","The Main Idea",[20,3422,3423,3434,3445,3468],{},[23,3424,3425,3426],{},"Terminal commands run from one folder at a time\n",[20,3427,3428],{},[23,3429,3430,3431],{},"That folder is the ",[2572,3432,3433],{},"working directory",[23,3435,3436,3439,3440],{},[39,3437,3438],{},"pwd",": print working directory\n",[20,3441,3442],{},[23,3443,3444],{},"Shows the full path to the folder your terminal is using",[23,3446,3447,3448],{},"Fresh terminal usually starts in your home folder\n",[20,3449,3450,3456,3462],{},[23,3451,3452,3453],{},"Windows Git Bash: ",[39,3454,3455],{},"\u002Fc\u002FUsers\u002Fyour-username",[23,3457,3458,3459],{},"Apple macOS: ",[39,3460,3461],{},"\u002FUsers\u002Fyour-username",[23,3463,3464,3465],{},"Linux: ",[39,3466,3467],{},"\u002Fhome\u002Fyour-username",[23,3469,3470,3471],{},"Commands from this lesson start from the working directory\n",[20,3472,3473],{},[23,3474,3475],{},"Unless you give a different path",[11,3477,3479,3482,3485,3537],{"id":3478,"level":14},"paths-relative-and-absolute",[16,3480,3481],{"id":3478},"Paths: Relative And Absolute",[53,3483,3484],{},"Paths build on the working directory. They tell the terminal which file or folder you mean",[20,3486,3487,3493,3499,3505,3531],{},[23,3488,3489,3490],{},"Relative path: starts from the working directory, like ",[39,3491,3492],{},"public\u002Findex.php",[23,3494,3495,3496],{},"Absolute path: starts from the system root, like ",[39,3497,3498],{},"\u002Fhome\u002Fstudent\u002Fproject",[23,3500,3501,3504],{},[39,3502,3503],{},"."," means the current folder",[23,3506,3507,3510,3511],{},[39,3508,3509],{},".."," means the parent folder\n",[20,3512,3513,3519,3525],{},[23,3514,3515,3518],{},[39,3516,3517],{},"..\u002F.."," goes up two folders",[23,3520,3521,3522],{},"Example: ",[39,3523,3524],{},"cd ..\u002F..",[23,3526,3527,3530],{},[39,3528,3529],{},"..."," is not a shortcut",[23,3532,3533,3536],{},[39,3534,3535],{},"~"," means your home folder",[53,3538,3539,3540,3542],{},"If a command affects the wrong place, check ",[39,3541,3438],{}," first, then check the path you typed",[11,3544,3546,3549,3552,3569,3572],{"id":3545,"level":14},"flags-options-and-arguments",[16,3547,3548],{"id":3545},"Flags, Options, And Arguments",[53,3550,3551],{},"Commands usually follow this shape:",[20,3553,3554,3559,3564],{},[23,3555,3556,3557],{},"Command: what to do, like ",[39,3558,1874],{},[23,3560,3561,3562],{},"Flag or option: how to do it, like ",[39,3563,3371],{},[23,3565,3566,3567],{},"Argument: what to do it to, like ",[39,3568,41],{},[53,3570,3571],{},"Examples:",[20,3573,3574,3580,3586],{},[23,3575,3576,3579],{},[39,3577,3578],{},"ls -a"," shows hidden files",[23,3581,3582,3585],{},[39,3583,3584],{},"cp -r folder backup-folder"," copies a folder",[23,3587,3588,3591],{},[39,3589,3590],{},"nano -l file.txt"," opens with line numbers",[11,3593,3595,3599,3602,3613],{"id":3594,"level":14},"practice-loop",[16,3596,3598],{"id":3597},"practice-1-location-and-paths","Practice 1: Location And Paths",[53,3600,3601],{},"For each command, use the same pattern:",[2491,3603,3604,3607,3610],{},[23,3605,3606],{},"Run one command",[23,3608,3609],{},"Read the output",[23,3611,3612],{},"Confirm the folder or file changed the way you expected",[20,3614,3615],{},[23,3616,3617],{},"See the slides below for workflow steps, checkpoints, and expected results",[11,3619,3621,3624,3626,3629,3632],{"id":3620,"level":265},"step-1-confirm-where-you-are",[16,3622,3623],{"id":3620},"Step 1: Confirm Where You Are",[53,3625,2298],{},[1533,3627],{"language":1535,"src":3628},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-1-confirm-where-you-01.sh",[53,3630,3631],{},"Expected result: a folder path",[53,3633,3634],{},"If you see a path, the terminal is working and you know your current location",[11,3636,3638,3641,3643,3646,3649,3652,3655],{"id":3637,"level":265},"step-2-list-files",[16,3639,3640],{"id":3637},"Step 2: List Files",[53,3642,2298],{},[1533,3644],{"language":1535,"src":3645},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-list-files-02.sh",[53,3647,3648],{},"Expected result: file and folder names from your current location",[53,3650,3651],{},"For hidden files and details too, run:",[1533,3653],{"language":1535,"src":3654},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-list-files-03.sh",[20,3656,3657,3662,3667],{},[23,3658,3659,3661],{},[39,3660,3371],{}," includes hidden files",[23,3663,3664,3666],{},[39,3665,3377],{}," uses a long listing",[23,3668,3669,3672],{},[39,3670,3671],{},"-la"," combines both",[11,3674,3676,3679,3682,3685,3692,3698],{"id":3675,"level":265},"step-3-change-folders",[16,3677,3678],{"id":3675},"Step 3: Change Folders",[53,3680,3681],{},"Start from your home folder, then move up and back",[1533,3683],{"language":1535,"src":3684},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-3-change-folders-04.sh",[53,3686,3687,3688,3691],{},"This avoids assuming your computer has a specific folder like ",[39,3689,3690],{},"Documents"," in the current location",[53,3693,3694,3695,3697],{},"When you move into a named folder later, run ",[39,3696,1874],{}," first and pick a folder that actually appears in the list",[53,3699,3700],{},"If a path has spaces, wrap it in quotes",[11,3702,3704,3708,3710,3713],{"id":3703,"level":265},"step-4-create-practice-folder",[16,3705,3707],{"id":3706},"step-4-create-a-practice-folder","Step 4: Create A Practice Folder",[53,3709,2298],{},[1533,3711],{"language":1535,"src":3712},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-4-create-a-practice-05.sh",[53,3714,3715,3716,3718,3719],{},"Expected result: ",[39,3717,3438],{}," ends with ",[39,3720,3721],{},"cli-practice",[11,3723,3725,3729,3731,3734,3737],{"id":3724,"level":265},"step-5-create-and-read-file",[16,3726,3728],{"id":3727},"step-5-write-text-to-a-file","Step 5: Write Text To A File",[53,3730,2298],{},[1533,3732],{"language":1535,"src":3733},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-5-write-text-to-a-f-06.sh",[53,3735,3736],{},"What this command does:",[20,3738,3739,3745,3751],{},[23,3740,3741,3744],{},[39,3742,3743],{},"echo"," prepares text for the terminal",[23,3746,3747,3750],{},[39,3748,3749],{},">"," redirects that text into a file instead of printing it on screen",[23,3752,3753,3756],{},[39,3754,3755],{},"cli-proof.txt"," is created in the current folder, or replaced if it already exists",[11,3758,3760,3764,3767,3770,3775],{"id":3759,"level":265},"step-5-read-file-back",[2565,3761,3763],{"id":3762},"step-5-continued-read-the-file-back","Step 5 Continued: Read The File Back",[53,3765,3766],{},"Then read it back:",[1533,3768],{"language":1535,"src":3769},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-5-continued-read-th-07.sh",[53,3771,3772,3774],{},[39,3773,1877],{}," prints file contents in the terminal",[53,3776,3777],{},"Expected result: the terminal prints the text you wrote",[11,3779,3781,3785,3787,3796,3799,3825,3828],{"id":3780,"level":14},"file-management-loop",[16,3782,3784],{"id":3783},"practice-2-file-management","Practice 2: File Management",[53,3786,3601],{},[2491,3788,3789,3791,3793],{},[23,3790,3606],{},[23,3792,3609],{},[23,3794,3795],{},"Confirm the file changed the way you expected",[53,3797,3798],{},"Commands in this practice:",[20,3800,3801,3807,3813,3819],{},[23,3802,3803,3806],{},[39,3804,3805],{},"touch"," creates an empty file",[23,3808,3809,3812],{},[39,3810,3811],{},"cp"," copies a file or folder",[23,3814,3815,3818],{},[39,3816,3817],{},"mv"," moves or renames",[23,3820,3821,3824],{},[39,3822,3823],{},"rm"," deletes",[53,3826,3827],{},"Important flags:",[20,3829,3830,3836,3842,3848],{},[23,3831,3832,3835],{},[39,3833,3834],{},"cp -r"," copies folders",[23,3837,3838,3841],{},[39,3839,3840],{},"rm -r"," deletes folders",[23,3843,3844,3847],{},[39,3845,3846],{},"rm -f"," forces deletion",[23,3849,3617],{},[11,3851,3853,3857,3859,3862,3867],{"id":3852,"level":265},"practice-2-step-1-create-empty-file",[16,3854,3856],{"id":3855},"step-1-create-an-empty-file","Step 1: Create An Empty File",[53,3858,2298],{},[1533,3860],{"language":1535,"src":3861},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-1-create-an-empty-f-08.sh",[53,3863,3864,3866],{},[39,3865,3805],{}," creates an empty file, or updates the timestamp if the file already exists",[53,3868,3715,3869,3872],{},[39,3870,3871],{},"practice-empty.txt"," appears in the folder list",[11,3874,3876,3880,3882,3885,3888,3893,3906],{"id":3875,"level":265},"practice-2-step-2-copy-rename-and-delete",[16,3877,3879],{"id":3878},"step-2-copy-rename-and-delete","Step 2: Copy, Rename, And Delete",[53,3881,2298],{},[1533,3883],{"language":1535,"src":3884},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-copy-rename-and-d-09.sh",[53,3886,3887],{},"Expected result: the backup is copied, renamed, then removed",[53,3889,547,3890,3892],{},[39,3891,3823],{}," carefully. Deleting from the terminal usually skips the recycle bin",[20,3894,3895,3900],{},[23,3896,3897,3899],{},[39,3898,3374],{},": recursive, includes folders and everything inside them",[23,3901,3902,3905],{},[39,3903,3904],{},"-f",": force, skips many confirmation prompts",[3907,3908,3910],"alert",{"color":3909},"red",[53,3911,3912,3913,3916],{},"Never run ",[39,3914,3915],{},"rm -rf \u002F",". It can try to delete the whole system from the root folder.",[11,3918,3920,3924,3927,3944,3949,3954,3973],{"id":3919,"level":14},"terminal-editors",[16,3921,3923],{"id":3922},"practice-3-terminal-editors","Practice 3: Terminal Editors",[53,3925,3926],{},"Sometimes you need to edit a file from a terminal",[20,3928,3929,3935],{},[23,3930,3931,3934],{},[39,3932,3933],{},"nano"," is beginner-friendly",[23,3936,3937,1574,3940,3943],{},[39,3938,3939],{},"vi",[39,3941,3942],{},"vim"," is common on servers but has a learning curve",[53,3945,547,3946,3948],{},[39,3947,3933],{}," for this course unless a lesson says otherwise",[53,3950,547,3951,3953],{},[39,3952,3590],{}," when line numbers would help",[53,3955,3956,3957,1574,3959,3961,3962,3965,3966,3969,3970,3972],{},"If you accidentally open ",[39,3958,3939],{},[39,3960,3942],{},", press ",[39,3963,3964],{},"Esc",", type ",[39,3967,3968],{},":q",", and press ",[39,3971,857],{}," to exit without saving",[20,3974,3975],{},[23,3976,3977],{},"See the slide below for workflow steps, checkpoints, and expected results",[11,3979,3981,3986,3988,3991,3995,4016],{"id":3980,"level":265},"edit-with-nano",[16,3982,3983,3984],{"id":3980},"Edit With ",[39,3985,3933],{},[53,3987,2298],{},[1533,3989],{"language":1535,"src":3990},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fedit-with-nano-10.sh",[53,3992,3066,3993,2078],{},[39,3994,3933],{},[20,3996,3997,4000,4006,4010],{},[23,3998,3999],{},"Type a short note",[23,4001,895,4002,4005],{},[39,4003,4004],{},"Ctrl+O"," to save",[23,4007,895,4008],{},[39,4009,857],{},[23,4011,895,4012,4015],{},[39,4013,4014],{},"Ctrl+X"," to exit",[53,4017,4018,4019,4021,4022,3965,4024,3969,4026],{},"If you open ",[39,4020,3939],{}," by mistake, press ",[39,4023,3964],{},[39,4025,3968],{},[39,4027,857],{},[11,4029,4031,4037,4042,4045,4048,4051],{"id":4030,"level":14},"sudo-and-permission-boundaries",[16,4032,4033,4036],{"id":4030},[39,4034,4035],{},"sudo"," And Permission Boundaries",[53,4038,4039,4041],{},[39,4040,4035],{}," runs a command with elevated permissions",[53,4043,4044],{},"Use it only when a setup lesson explicitly says to use it",[53,4046,4047],{},"Example:",[1533,4049],{"language":1535,"src":4050},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fsudo-and-permission-boun-11.sh",[20,4052,4053],{},[23,4054,4055],{},"See the slide below for supporting examples and follow-up details",[11,4057,4059,4064,4070],{"id":4058,"level":265},"sudo-by-operating-system",[2565,4060,4061,4063],{"id":4058},[39,4062,4035],{}," By Operating System",[53,4065,4066,4067,4069],{},"On Linux and macOS, ",[39,4068,4035],{}," is common for package installation and service management",[53,4071,4072,4073,4075],{},"Modern Windows also has a native ",[39,4074,4035],{}," option, but Windows Git Bash usually does not need it for this course. If elevated access is needed on Windows, open Git Bash as administrator",[11,4077,4079,4082,4085,4096],{"id":4078,"level":14},"quick-safety-routine",[16,4080,4081],{"id":4078},"Quick Safety Routine",[53,4083,4084],{},"Before a command changes files, ask:",[20,4086,4087,4090,4093],{},[23,4088,4089],{},"What folder am I in?",[23,4091,4092],{},"Do I see the files I expect?",[23,4094,4095],{},"Am I about to change the right folder?",[53,4097,4098,4099,4101,4102],{},"If one answer is unclear, stop and run ",[39,4100,3438],{}," plus ",[39,4103,4104],{},"ls -la",[11,4106,4108,4111],{"id":4107,"level":14},"common-mistakes",[16,4109,4110],{"id":4107},"Common Mistakes",[20,4112,4113,4129,4135,4143],{},[23,4114,4115,4118,4119,4121,4122,4124,4125,4128],{},[39,4116,4117],{},"No such file or directory",": run ",[39,4120,3438],{},", then ",[39,4123,1874],{},", then try ",[39,4126,4127],{},"cd"," again",[23,4130,4131,4132,4134],{},"Command affected the wrong folder: check ",[39,4133,3438],{}," before continuing",[23,4136,4137,4139,4140,4142],{},[39,4138,1877],{}," cannot find the file: run ",[39,4141,4104],{}," and check the exact filename",[23,4144,4055],{},[11,4146,4148,4152],{"id":4147,"level":265},"common-mistakes-recovery",[2565,4149,4151],{"id":4150},"recovery-checks","Recovery Checks",[20,4153,4154,4157,4163,4169],{},[23,4155,4156],{},"Spaces in a path: wrap the path in quotes",[23,4158,4159,4160],{},"Command keeps running: press ",[39,4161,4162],{},"Ctrl+C",[23,4164,4165,4166],{},"Permission denied: move back home with ",[39,4167,4168],{},"cd ~",[23,4170,4171,4172,4174],{},"Wrong ",[39,4173,3823],{},": stop and ask before doing more work",[11,4176,4177,4179,4182],{"id":3197,"level":14},[16,4178,3200],{"id":3197},[53,4180,4181],{},"You are ready for the next setup lesson when these commands make sense:",[1533,4183],{"language":1535,"src":4184},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fquick-check-12.sh",[11,4186,4187,4189],{"id":2611,"level":14},[16,4188,2559],{"id":2556},[270,4190,4191,4221],{"gap":272,"left-width":1592,"right-width":1592},[277,4192,4193,4195,4201,4210],{"v-slot:left":279},[2565,4194,2568],{"id":2567},[53,4196,4197,4200],{},[2572,4198,4199],{},"Working directory"," - The folder where the next terminal command runs",[53,4202,4203,4206,4207],{},[2572,4204,4205],{},"Path"," - A file or folder location, such as ",[39,4208,4209],{},"public_html\u002Findex.php",[53,4211,4212,4215,4216,4218,4219],{},[2572,4213,4214],{},"Flag"," - An extra command option, such as ",[39,4217,3671],{}," in ",[39,4220,4104],{},[277,4222,4223,4225],{"v-slot:right":279},[2565,4224,2612],{"id":2611},[20,4226,4227,4234,4241],{},[23,4228,4229],{},[146,4230,4233],{"href":4231,"rel":4232},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Fdesktop\u002Fen\u002Flatest\u002Ftutorial\u002Fthe-linux-command-line-for-beginners\u002F",[150],"Ubuntu Tutorial: The Linux Command Line For Beginners",[23,4235,4236],{},[146,4237,4240],{"href":4238,"rel":4239},"https:\u002F\u002Fwww.gnu.org\u002Fsoftware\u002Fcoreutils\u002Fmanual\u002Fcoreutils.html",[150],"GNU Coreutils Manual",[23,4242,4243],{},[146,4244,4247],{"href":4245,"rel":4246},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FLearn_web_development\u002FGetting_started\u002FEnvironment_setup\u002FCommand_line",[150],"MDN: Command Line Crash Course",[11,4249,4250,4252,4254],{"id":2664,"level":14},[16,4251,2667],{"id":2664},[53,4253,2670],{},[20,4255,4256,4261,4266,4277,4291],{},[23,4257,547,4258,4260],{},[39,4259,3438],{}," to check where commands will run",[23,4262,547,4263,4265],{},[39,4264,4104],{}," to inspect the current folder",[23,4267,547,4268,2269,4270,2269,4272,2272,4274,4276],{},[39,4269,4127],{},[39,4271,3503],{},[39,4273,3509],{},[39,4275,3535],{}," to move intentionally",[23,4278,4279,4280,2269,4282,2269,4284,2269,4286,2272,4288,4290],{},"Use file commands such as ",[39,4281,3805],{},[39,4283,3811],{},[39,4285,3817],{},[39,4287,3823],{},[39,4289,3933],{}," carefully",[23,4292,4293],{},"Stop and check location when output does not match the lesson",{"title":279,"searchDepth":2694,"depth":2694,"links":4295},[4296,4297,4298,4299,4300,4301,4302,4303,4304,4305,4306,4307,4310,4311,4312,4313,4314,4316,4321,4322,4325,4326,4327],{"id":3296,"depth":2694,"text":3297},{"id":3351,"depth":2694,"text":3354},{"id":132,"depth":2694,"text":135},{"id":3419,"depth":2694,"text":3420},{"id":3478,"depth":2694,"text":3481},{"id":3545,"depth":2694,"text":3548},{"id":3597,"depth":2694,"text":3598},{"id":3620,"depth":2694,"text":3623},{"id":3637,"depth":2694,"text":3640},{"id":3675,"depth":2694,"text":3678},{"id":3706,"depth":2694,"text":3707},{"id":3727,"depth":2694,"text":3728,"children":4308},[4309],{"id":3762,"depth":3262,"text":3763},{"id":3783,"depth":2694,"text":3784},{"id":3855,"depth":2694,"text":3856},{"id":3878,"depth":2694,"text":3879},{"id":3922,"depth":2694,"text":3923},{"id":3980,"depth":2694,"text":4315},"Edit With nano",{"id":4030,"depth":2694,"text":4317,"children":4318},"sudo And Permission Boundaries",[4319],{"id":4058,"depth":3262,"text":4320},"sudo By Operating System",{"id":4078,"depth":2694,"text":4081},{"id":4107,"depth":2694,"text":4110,"children":4323},[4324],{"id":4150,"depth":3262,"text":4151},{"id":3197,"depth":2694,"text":3200},{"id":2556,"depth":2694,"text":2559},{"id":2664,"depth":2694,"text":2667},"Practice the terminal commands you need so you can move through folders, inspect files, and verify your location before running course commands.","Face-to-face class of about 40 students; includes short CLI demo, student command practice, path\u002Fflag checks, and common beginner recovery questions.","45","55",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands",{"title":3288,"description":4328},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands",[4337,4338,4339],"cli","terminal","filesystem","46:05","NsSRKv_uBWM","https:\u002F\u002Fyoutu.be\u002FNsSRKv_uBWM","q_NRWUOCcsk5lm6u6kKPFGl9E9VqeQhaC0qb86nD7aY",{"id":4345,"title":4346,"audience":6,"body":4347,"contentType":2762,"course":2763,"description":5210,"estimateBasis":5211,"estimatedDiscussionMinutes":3268,"estimatedLiveMinutes":5212,"estimatedTotalMinutes":4330,"extension":871,"meta":5213,"module":569,"navigation":2770,"order":3269,"path":5214,"promptAssist":2773,"seo":5215,"status":2775,"stem":5216,"tags":5217,"videoDuration":5218,"videoId":5219,"videoLink":5220,"videoTitle":4346,"week":569,"__hash__":5221},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools.md","Git Tools",{"type":8,"value":4348,"toc":5180},[4349,4372,4401,4429,4463,4494,4526,4561,4590,4620,4656,4658,4688,4719,4748,4797,4815,4832,4852,4877,4907,4925,4966,5010,5091,5151],[11,4350,4351,4353],{"id":3351,"level":14},[16,4352,3354],{"id":3351},[20,4354,4355,4358,4361],{},[23,4356,4357],{},"Install Git",[23,4359,4360],{},"Choose one terminal for your operating system",[23,4362,4363,4364,2269,4367,2272,4369,4371],{},"Confirm ",[39,4365,4366],{},"git --version",[39,4368,3438],{},[39,4370,4104],{}," work before GitHub setup",[11,4373,4375,4379],{"id":4374,"level":14},"terminal-choice-by-os",[16,4376,4378],{"id":4377},"terminal-choices","Terminal Choices",[20,4380,4381,4384,4387,4390,4392,4395,4398],{},[23,4382,4383],{},"Pick the terminal for your operating system",[23,4385,4386],{},"Use that same terminal for this lesson path",[23,4388,4389],{},"Run commands on your own computer unless a later lesson explicitly says \"inside the VM\"",[23,4391,3395],{},[23,4393,4394],{},"Apple macOS: Terminal, with iTerm2 optional",[23,4396,4397],{},"Linux: Terminal, with Tilix optional",[23,4399,4400],{},"These operating system notes are alternatives, not a sequence",[11,4402,4404,4408,4426],{"id":4403,"level":14},"step-1-install-git-on-windows",[16,4405,4407],{"id":4406},"windows-path-git-bash","Windows Path: Git Bash",[2491,4409,4410,4417,4420,4423],{},[23,4411,4412,4413],{},"Go to ",[146,4414,4415],{"href":4415,"rel":4416},"https:\u002F\u002Fgit-scm.com\u002Finstall\u002Fwindows",[150],[23,4418,4419],{},"Download and run the Git for Windows installer",[23,4421,4422],{},"Open Git Bash from the Start menu",[23,4424,4425],{},"Use Git Bash whenever this course says to use the terminal",[53,4427,4428],{},"See the slides below for the install settings, launch check, and Windows terminal habit",[11,4430,4432,4435],{"id":4431,"level":265},"windows-installer-components",[2565,4433,4434],{"id":4431},"Windows Installer: Components",[270,4436,4437,4445],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,4438,4439],{"v-slot:left":279},[53,4440,4441],{},[283,4442],{"alt":4443,"src":4444,"variant":287},"Git for Windows installer component selection screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep01_components.png",[277,4446,4447],{"v-slot:right":279},[20,4448,4449,4452,4457],{},[23,4450,4451],{},"Recommended to have these components selected",[23,4453,652,4454],{},[39,4455,4456],{},"Git Bash Here",[23,4458,4459,4460],{},"Continue with ",[39,4461,4462],{},"Next",[11,4464,4466,4469],{"id":4465,"level":265},"windows-installer-default-editor",[2565,4467,4468],{"id":4465},"Windows Installer: Default Editor",[270,4470,4471,4479],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,4472,4473],{"v-slot:left":279},[53,4474,4475],{},[283,4476],{"alt":4477,"src":4478,"variant":287},"Git for Windows installer default editor selection screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep02_default_editor.png",[277,4480,4481],{"v-slot:right":279},[20,4482,4483,4486,4491],{},[23,4484,4485],{},"Choose the editor you are comfortable with",[23,4487,4488,4490],{},[39,4489,3933],{}," or VS Code is friendlier than Vim for most beginners",[23,4492,4493],{},"This setting affects Git messages if Git opens an editor",[11,4495,4497,4500],{"id":4496,"level":265},"windows-installer-branch-name",[2565,4498,4499],{"id":4496},"Windows Installer: Branch Name",[270,4501,4502,4510],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,4503,4504],{"v-slot:left":279},[53,4505,4506],{},[283,4507],{"alt":4508,"src":4509,"variant":287},"Git for Windows installer default branch name screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep03_branch_naming.png",[277,4511,4512],{"v-slot:right":279},[20,4513,4514,4520,4523],{},[23,4515,4516,4517],{},"Select the option that uses ",[39,4518,4519],{},"main",[23,4521,4522],{},"Course repositories will tell you which branch to use later",[23,4524,4525],{},"Do not create custom branch names here",[11,4527,4529,4532],{"id":4528,"level":265},"windows-installer-path",[2565,4530,4531],{"id":4528},"Windows Installer: PATH",[270,4533,4534,4542],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,4535,4536],{"v-slot:left":279},[53,4537,4538],{},[283,4539],{"alt":4540,"src":4541,"variant":287},"Git for Windows installer PATH environment screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep04_path.png",[277,4543,4544],{"v-slot:right":279},[20,4545,4546,4549,4555,4558],{},[23,4547,4548],{},"Select the recommended PATH option",[23,4550,4551,4552],{},"This lets Git Bash and common tools find ",[39,4553,4554],{},"git",[23,4556,4557],{},"Avoid options that say Git Bash only",[23,4559,4560],{},"The third option can be used if you understand the consequences",[11,4562,4564,4567],{"id":4563,"level":265},"windows-installer-ssh",[2565,4565,4566],{"id":4563},"Windows Installer: SSH",[270,4568,4569,4577],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,4570,4571],{"v-slot:left":279},[53,4572,4573],{},[283,4574],{"alt":4575,"src":4576,"variant":287},"Git for Windows installer SSH executable screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep05_ssh_bundled.png",[277,4578,4579],{"v-slot:right":279},[20,4580,4581,4584,4587],{},[23,4582,4583],{},"Use the bundled OpenSSH option",[23,4585,4586],{},"This keeps Git Bash SSH behavior predictable",[23,4588,4589],{},"SSH setup happens in the next lesson",[11,4591,4593,4597],{"id":4592,"level":265},"windows-installer-openssl",[2565,4594,4596],{"id":4595},"windows-installer-https","Windows Installer: HTTPS",[270,4598,4599,4607],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,4600,4601],{"v-slot:left":279},[53,4602,4603],{},[283,4604],{"alt":4605,"src":4606,"variant":287},"Git for Windows installer HTTPS transport backend screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep06_openssl.png",[277,4608,4609],{"v-slot:right":279},[20,4610,4611,4614,4617],{},[23,4612,4613],{},"Keep the OpenSSL option",[23,4615,4616],{},"This is the normal Git for Windows choice",[23,4618,4619],{},"It supports secure GitHub connections",[11,4621,4623,4627],{"id":4622,"level":265},"windows-installer-checkout-style",[2565,4624,4626],{"id":4625},"windows-installer-line-endings","Windows Installer: Line Endings",[270,4628,4629,4637],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,4630,4631],{"v-slot:left":279},[53,4632,4633],{},[283,4634],{"alt":4635,"src":4636,"variant":287},"Git for Windows installer line ending conversion screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep07_checkout_style.png",[277,4638,4639,4650],{"v-slot:right":279},[20,4640,4641,4644,4647],{},[23,4642,4643],{},"Keep the default line-ending option",[23,4645,4646],{},"Git handles Windows and Linux line endings for you",[23,4648,4649],{},"Do not change this unless a lesson says to",[124,4651,4653],{"type":4652},"note",[53,4654,4655],{},"Line-ending warnings may appear later. They are usually informational, not a sign that there's an issue.",[53,4657,1410],{},[11,4659,4661,4665],{"id":4660,"level":265},"windows-installer-mintty",[2565,4662,4664],{"id":4663},"windows-installer-terminal-emulator","Windows Installer: Terminal Emulator",[270,4666,4667,4675],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,4668,4669],{"v-slot:left":279},[53,4670,4671],{},[283,4672],{"alt":4673,"src":4674,"variant":287},"Git for Windows installer terminal emulator screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep08_mintty.png",[277,4676,4677],{"v-slot:right":279},[20,4678,4679,4682,4685],{},[23,4680,4681],{},"Keep MinTTY selected",[23,4683,4684],{},"This is the normal Git Bash window",[23,4686,4687],{},"Course screenshots will assume this terminal style",[11,4689,4691,4695],{"id":4690,"level":265},"windows-installer-fast-forward",[2565,4692,4694],{"id":4693},"windows-installer-pull-behavior","Windows Installer: Pull Behavior",[270,4696,4697,4705],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,4698,4699],{"v-slot:left":279},[53,4700,4701],{},[283,4702],{"alt":4703,"src":4704,"variant":287},"Git for Windows installer git pull behavior screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep09_ff_merge.png",[277,4706,4707],{"v-slot:right":279},[20,4708,4709,4716],{},[23,4710,4711,4712,4715],{},"Keep the default ",[39,4713,4714],{},"git pull"," behavior",[23,4717,4718],{},"Later lessons explain pull, merge, and conflicts",[11,4720,4722,4725],{"id":4721,"level":265},"windows-installer-credential-manager",[2565,4723,4724],{"id":4721},"Windows Installer: Credential Manager",[270,4726,4727,4735],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,4728,4729],{"v-slot:left":279},[53,4730,4731],{},[283,4732],{"alt":4733,"src":4734,"variant":287},"Git for Windows installer credential manager screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep10_credential_manager.png",[277,4736,4737],{"v-slot:right":279},[20,4738,4739,4742,4745],{},[23,4740,4741],{},"Keep Git Credential Manager enabled",[23,4743,4744],{},"It helps with browser-based GitHub sign-in",[23,4746,4747],{},"This course still uses SSH for repo pushes",[11,4749,4751,4754],{"id":4750,"level":265},"windows-installer-extra-options",[2565,4752,4753],{"id":4750},"Windows Installer: Extra Options",[270,4755,4756,4764],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,4757,4758],{"v-slot:left":279},[53,4759,4760],{},[283,4761],{"alt":4762,"src":4763,"variant":287},"Git for Windows installer extra options screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep11_extra_options_optional.png",[277,4765,4766],{"v-slot:right":279},[20,4767,4768,4776,4787,4795],{},[23,4769,4770,4771],{},"Enable file system caching\n",[20,4772,4773],{},[23,4774,4775],{},"Improves Git performance on Windows",[23,4777,4778,4779],{},"Enable symbolic links if available\n",[20,4780,4781,4784],{},[23,4782,4783],{},"Helps Git handle link-like files correctly",[23,4785,4786],{},"May require Windows Developer Mode or admin rights",[23,4788,4789,4790],{},"Skip experimental options\n",[20,4791,4792],{},[23,4793,4794],{},"They can change behavior between Git versions",[23,4796,468],{},[11,4798,4800,4804],{"id":4799,"level":265},"step-1-open-git-bash-on-windows",[2565,4801,4803],{"id":4802},"open-git-bash","Open Git Bash",[20,4805,4806,4809,4812],{},[23,4807,4808],{},"Start menu -> Git Bash",[23,4810,4811],{},"Pin it if that helps you find the same terminal later",[23,4813,4814],{},"Run the checks in the next slides from Git Bash",[11,4816,4818,4821],{"id":4817,"level":265},"windows-terminal-habit",[2565,4819,4820],{"id":4817},"Windows Terminal Habit",[20,4822,4823,4826,4829],{},[23,4824,4825],{},"Use Git Bash for course commands on Windows",[23,4827,4828],{},"If another terminal opens by accident, close it and open Git Bash",[23,4830,4831],{},"Staying in one terminal makes setup problems easier to diagnose",[11,4833,4835,4838],{"id":4834,"level":14},"macos-path-terminal",[16,4836,4837],{"id":4834},"macOS Path: Terminal",[20,4839,4840,4843,4846,4849],{},[23,4841,4842],{},"Built-in Terminal is fully supported",[23,4844,4845],{},"Optional iTerm2 gives you tabs, split panes, and profiles",[23,4847,4848],{},"Beginner default: start with Terminal unless you already prefer iTerm2",[23,4850,4851],{},"See the slide below for the optional modern terminal install path",[11,4853,4855,4859],{"id":4854,"level":265},"macos-optional-iterm2-install",[2565,4856,4858],{"id":4857},"optional-iterm2-install","Optional iTerm2 Install",[20,4860,4861,4868,4871,4874],{},[23,4862,4863,4864],{},"Download the stable release from ",[146,4865,4866],{"href":4866,"rel":4867},"https:\u002F\u002Fiterm2.com\u002Fdownloads.html",[150],[23,4869,4870],{},"Move iTerm2 to Applications",[23,4872,4873],{},"Open iTerm2 and run the same checks as Terminal",[23,4875,4876],{},"Use Terminal or iTerm2 consistently for course commands",[11,4878,4880,4883,4896,4899,4902],{"id":4879,"level":14},"linux-path-terminal",[16,4881,4882],{"id":4879},"Linux Path: Terminal",[20,4884,4885,4888,4891],{},[23,4886,4887],{},"Open the built-in Terminal app",[23,4889,4890],{},"Git is often installed already",[23,4892,1629,4893,4895],{},[39,4894,4366],{}," fails, use your distribution package manager",[53,4897,4898],{},"For Ubuntu:",[1533,4900],{"language":1535,"src":4901},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Flinux-path-terminal-01.sh",[20,4903,4904],{},[23,4905,4906],{},"See the slide below for the optional split-pane terminal setup",[11,4908,4910,4914,4917,4919,4922],{"id":4909,"level":265},"linux-optional-tilix-install",[2565,4911,4913],{"id":4912},"optional-tilix-install","Optional Tilix Install",[53,4915,4916],{},"Tilix is a Linux terminal with split panes and profiles",[53,4918,4898],{},[1533,4920],{"language":1535,"src":4921},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Foptional-tilix-install-02.sh",[53,4923,4924],{},"Use the built-in Terminal if optional installs add friction",[11,4926,4928,4932],{"id":4927,"level":14},"step-3-confirm-git-and-shell",[16,4929,4931],{"id":4930},"confirm-git-and-shell","Confirm Git And Shell",[270,4933,4936,4950],{"gap":272,"left-width":4934,"right-width":4935},"1.15fr","0.85fr",[277,4937,4938,4940,4943,4946],{"v-slot:left":279},[53,4939,2298],{},[1533,4941],{"language":1535,"src":4942},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fconfirm-git-and-shell-03.sh",[53,4944,4945],{},"Expected output:",[1533,4947],{"language":4948,"src":4949},"plaintext","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fexample-output-04.txt",[277,4951,4952,4955],{"v-slot:right":279},[53,4953,4954],{},"This confirms:",[20,4956,4957,4960,4963],{},[23,4958,4959],{},"Git is installed",[23,4961,4962],{},"The terminal can find Git",[23,4964,4965],{},"Your shell matches later course commands",[11,4967,4969,4973],{"id":4968,"level":14},"step-4-cli-safety-check-before-every-git-command",[16,4970,4972],{"id":4971},"check-location-before-git-commands","Check Location Before Git Commands",[270,4974,4975,4987],{"gap":272,"left-width":1591,"right-width":274},[277,4976,4977,4979,4982,4984],{"v-slot:left":279},[53,4978,2298],{},[1533,4980],{"language":1535,"src":4981},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fcheck-location-before-git-commands-05.sh",[53,4983,4945],{},[1533,4985],{"language":4948,"src":4986},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fexample-output-06.txt",[277,4988,4989,4992],{"v-slot:right":279},[53,4990,4991],{},"Use this before Git commands:",[20,4993,4994,4999,5004,5007],{},[23,4995,4996,4998],{},[39,4997,3438],{}," shows the current folder",[23,5000,5001,5003],{},[39,5002,4104],{}," shows what is inside it",[23,5005,5006],{},"If the folder is wrong, fix location first",[23,5008,5009],{},"Do not run Git commands while guessing",[11,5011,5012,5014],{"id":4107,"level":14},[16,5013,4110],{"id":4107},[270,5015,5016,5058],{"gap":272,"left-width":1592,"right-width":1592},[277,5017,5018],{"v-slot:left":279},[20,5019,5020,5033,5050],{},[23,5021,5022,5025],{},[39,5023,5024],{},"git: command not found",[20,5026,5027,5030],{},[23,5028,5029],{},"Git is missing, or this terminal cannot find it",[23,5031,5032],{},"Close the terminal and reopen the correct one",[23,5034,5035,5038],{},[39,5036,5037],{},"not a git repository",[20,5039,5040,5043],{},[23,5041,5042],{},"The command ran outside a cloned repository",[23,5044,547,5045,1732,5047,5049],{},[39,5046,3438],{},[39,5048,4104],{},", then move to the repo folder",[23,5051,5052,5053],{},"Wrong terminal",[20,5054,5055],{},[23,5056,5057],{},"Windows users should switch back to Git Bash",[277,5059,5060,5063],{"v-slot:right":279},[23,5061,5062],{},"Too many terminals open",[2491,5064,5065,5068,5078,5082,5088],{},[23,5066,5067],{},"Close extra terminal windows",[23,5069,5070,5071],{},"Open the correct terminal\n",[20,5072,5073,5075],{},[23,5074,3395],{},[23,5076,5077],{},"Apple macOS\u002FLinux: Terminal",[23,5079,1729,5080],{},[39,5081,4366],{},[23,5083,1729,5084,1732,5086],{},[39,5085,3438],{},[39,5087,4104],{},[23,5089,5090],{},"Continue only after the folder looks right",[11,5092,5093,5095],{"id":2611,"level":14},[16,5094,2559],{"id":2556},[270,5096,5097,5119],{"gap":272,"left-width":1592,"right-width":1592},[277,5098,5099,5101,5107,5113],{"v-slot:left":279},[2565,5100,2568],{"id":2567},[53,5102,5103,5106],{},[2572,5104,5105],{},"Terminal"," - A text-based interface where you type commands to control your computer",[53,5108,5109,5112],{},[2572,5110,5111],{},"CLI (Command Line Interface)"," - The text-based interface where you type commands",[53,5114,5115,5118],{},[2572,5116,5117],{},"Git"," - A tool for tracking changes in code files over time",[277,5120,5121,5123],{"v-slot:right":279},[2565,5122,2612],{"id":2611},[20,5124,5125,5132,5138,5144],{},[23,5126,5127],{},[146,5128,5131],{"href":5129,"rel":5130},"https:\u002F\u002Fgit-scm.com\u002Fdownloads",[150],"Git Downloads",[23,5133,5134],{},[146,5135,5137],{"href":4415,"rel":5136},[150],"Git For Windows Install Page",[23,5139,5140],{},[146,5141,5143],{"href":4866,"rel":5142},[150],"iTerm2 Downloads",[23,5145,5146],{},[146,5147,5150],{"href":5148,"rel":5149},"https:\u002F\u002Fgnunn1.github.io\u002Ftilix-web\u002F",[150],"Tilix",[11,5152,5153,5155,5158],{"id":2664,"level":14},[16,5154,2667],{"id":2664},[53,5156,5157],{},"Before moving on, confirm you can:",[20,5159,5160,5163,5167,5174,5177],{},[23,5161,5162],{},"Open the correct terminal for your operating system",[23,5164,1729,5165],{},[39,5166,4366],{},[23,5168,547,5169,1732,5171,5173],{},[39,5170,3438],{},[39,5172,4104],{}," to check your location",[23,5175,5176],{},"Understand what terminal\u002FCLI refers to",[23,5178,5179],{},"Keep track of terminal instances",{"title":279,"searchDepth":2694,"depth":2694,"links":5181},[5182,5183,5184,5199,5202,5205,5206,5207,5208,5209],{"id":3351,"depth":2694,"text":3354},{"id":4377,"depth":2694,"text":4378},{"id":4406,"depth":2694,"text":4407,"children":5185},[5186,5187,5188,5189,5190,5191,5192,5193,5194,5195,5196,5197,5198],{"id":4431,"depth":3262,"text":4434},{"id":4465,"depth":3262,"text":4468},{"id":4496,"depth":3262,"text":4499},{"id":4528,"depth":3262,"text":4531},{"id":4563,"depth":3262,"text":4566},{"id":4595,"depth":3262,"text":4596},{"id":4625,"depth":3262,"text":4626},{"id":4663,"depth":3262,"text":4664},{"id":4693,"depth":3262,"text":4694},{"id":4721,"depth":3262,"text":4724},{"id":4750,"depth":3262,"text":4753},{"id":4802,"depth":3262,"text":4803},{"id":4817,"depth":3262,"text":4820},{"id":4834,"depth":2694,"text":4837,"children":5200},[5201],{"id":4857,"depth":3262,"text":4858},{"id":4879,"depth":2694,"text":4882,"children":5203},[5204],{"id":4912,"depth":3262,"text":4913},{"id":4930,"depth":2694,"text":4931},{"id":4971,"depth":2694,"text":4972},{"id":4107,"depth":2694,"text":4110},{"id":2556,"depth":2694,"text":2559},{"id":2664,"depth":2694,"text":2667},"Install Git and choose the correct terminal for course commands.","Face-to-face class of about 40 students; includes OS-specific terminal choices, Git installation, short checks, and setup friction.","35",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools",{"title":4346,"description":5210},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools",[4554,4338,3280],"21:30","u1x5bq-JmCg","https:\u002F\u002Fyoutu.be\u002Fu1x5bq-JmCg","71DrP8YI_ks4jUswWJXy9rmZOVVoeaJAEPancHNHsV4",{"id":5223,"title":5224,"audience":6,"body":5225,"contentType":2762,"course":2763,"description":6296,"estimateBasis":6297,"estimatedDiscussionMinutes":6298,"estimatedLiveMinutes":6299,"estimatedTotalMinutes":6300,"extension":871,"meta":6301,"module":569,"navigation":2770,"order":3270,"path":6302,"promptAssist":2773,"seo":6303,"status":2775,"stem":6304,"tags":6305,"videoDuration":6308,"videoId":6309,"videoLink":6310,"videoTitle":6311,"week":569,"__hash__":6312},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh.md","Set Up GitHub SSH",{"type":8,"value":5226,"toc":6268},[5227,5253,5271,5296,5309,5336,5373,5448,5496,5563,5639,5681,5707,5739,5777,5822,5855,5923,5925,5928,5939,6011,6040,6074,6122,6168,6236],[11,5228,5230,5233],{"id":5229,"level":14},"goals",[16,5231,5232],{"id":5229},"Goals",[20,5234,5235,5238,5241,5244,5247,5250],{},[23,5236,5237],{},"Confirm Git works in the correct terminal",[23,5239,5240],{},"Sign in to GitHub with a school or personal account",[23,5242,5243],{},"Create or reuse an SSH key for GitHub",[23,5245,5246],{},"Add the public key to GitHub",[23,5248,5249],{},"Create and clone your course repository",[23,5251,5252],{},"Set Git identity inside the cloned repository",[11,5254,5256,5259,5268],{"id":5255,"level":14},"terminal-by-os",[16,5257,5258],{"id":5255},"Terminal By OS",[20,5260,5261,5263,5266],{},[23,5262,3395],{},[23,5264,5265],{},"Apple macOS: Terminal or iTerm2",[23,5267,3410],{},[53,5269,5270],{},"Run these commands on your own computer",[11,5272,5274,5277],{"id":5273,"level":14},"git-and-ssh-terms",[16,5275,5276],{"id":5273},"Git And SSH Terms",[20,5278,5279,5282,5290,5293],{},[23,5280,5281],{},"Git identity: name and email attached to commits in a repository",[23,5283,5284,5285],{},"SSH key pair: private key stays on your computer, public key goes to GitHub\n",[20,5286,5287],{},[23,5288,5289],{},"This is how we'll authenticate to GitHub",[23,5291,5292],{},"SSH agent: helper that keeps your private key available to Git commands",[23,5294,5295],{},"Clone: local folder connected to a GitHub repository",[11,5297,5299,5302,5306],{"id":5298,"level":14},"ssh-key-flow",[16,5300,5301],{"id":5298},"SSH Key Flow",[5303,5304],"mermaid",{"code":5305},"sequenceDiagram\n  participant Terminal\n  participant PrivateKey as Private key on your computer\n  participant GitHub as Public key in GitHub\n  Terminal->>PrivateKey: Load key with ssh-add\n  Terminal->>GitHub: Ask to authenticate\n  GitHub-->>Terminal: Confirm matching public key\n",[53,5307,5308],{},"GitHub receives only the public key. The private key stays on your computer",[11,5310,5312,5315],{"id":5311,"level":14},"step-1-check-git",[16,5313,5314],{"id":5311},"Step 1: Check Git",[270,5316,5317,5325],{"gap":272,"left-width":1592,"right-width":1592},[277,5318,5319,5321],{"v-slot:left":279},[53,5320,2298],{},[1533,5322],{"label":5323,"language":1535,"src":5324},"check-git.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-1-check-git-01.sh",[277,5326,5327,5329,5333],{"v-slot:right":279},[53,5328,4945],{},[1533,5330],{"label":5331,"language":4948,"src":5332},"example-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-02.txt",[53,5334,5335],{},"A valid version means Git is installed and available in this terminal",[11,5337,5339,5343],{"id":5338,"level":14},"step-2-github-account",[16,5340,5342],{"id":5341},"step-2-sign-in-to-github","Step 2: Sign In To GitHub",[270,5344,5346,5365],{"gap":272,"left-width":1592,"right-width":5345},"0.8fr",[277,5347,5348],{"v-slot:left":279},[20,5349,5350,5353,5356,5359,5362],{},[23,5351,5352],{},"Use an existing GitHub account or create one",[23,5354,5355],{},"School email recommended for course identity",[23,5357,5358],{},"Personal email is fine if you prefer it",[23,5360,5361],{},"Avoid work email so course access does not depend on an employer account",[23,5363,5364],{},"Confirm you can open GitHub Settings before continuing",[277,5366,5367],{"v-slot:right":279},[53,5368,5369],{},[283,5370],{"alt":5371,"src":5372,"variant":287},"GitHub account menu open with Settings visible","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fgithub-logged-in.png",[11,5374,5376,5380],{"id":5375,"level":14},"step-2-create-repo",[16,5377,5379],{"id":5378},"step-3-create-course-repository","Step 3: Create Course Repository",[270,5381,5382,5440],{"gap":272,"left-width":484,"right-width":4934},[277,5383,5384,5387],{"v-slot:left":279},[53,5385,5386],{},"In GitHub:",[20,5388,5389,5394,5399,5405,5420,5426,5429,5437],{},[23,5390,774,5391],{},[39,5392,5393],{},"+",[23,5395,889,5396],{},[39,5397,5398],{},"New repository",[23,5400,5401,5402],{},"Name it ",[39,5403,5404],{},"\u003Cucid>-IT202-\u003Csection>-\u003CsemYear>",[23,5406,5407,5408,5411,5412,5415,5416,5419],{},"Semester code examples: ",[39,5409,5410],{},"S2026"," spring, ",[39,5413,5414],{},"M2026"," summer, ",[39,5417,5418],{},"F2026"," fall",[23,5421,5422,5423],{},"Set visibility to ",[39,5424,5425],{},"Private",[23,5427,5428],{},"Toggle \"Add README\"",[23,5430,5431,5432],{},"Do not toggle \"Add .gitignore\"",[20,5433,5434],{},[23,5435,5436],{},"A future lesson will discuss and add this important file",[23,5438,5439],{},"Do not add starter files unless instructed",[277,5441,5442],{"v-slot:right":279},[53,5443,5444],{},[283,5445],{"alt":5446,"src":5447,"variant":287},"GitHub new repository form with course naming pattern, private visibility, and README enabled","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fnew-repo.png",[11,5449,5451,5455,5482],{"id":5450,"level":14},"step-3-check-existing-key",[16,5452,5454],{"id":5453},"step-4-check-for-existing-ssh-key","Step 4: Check For Existing SSH Key",[270,5456,5457,5465],{"gap":272,"left-width":1592,"right-width":1592},[277,5458,5459,5461],{"v-slot:left":279},[53,5460,2298],{},[1533,5462],{"label":5463,"language":1535,"src":5464},"check-ssh-folder.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-3-check-for-existing-ssh-key-03.sh",[277,5466,5467,5470,5473],{"v-slot:right":279},[53,5468,5469],{},"Example output:",[1533,5471],{"label":5331,"language":4948,"src":5472},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-04.txt",[53,5474,5475,5476,1732,5479],{},"Look for a matching GitHub-specific pair such as ",[39,5477,5478],{},"github_key",[39,5480,5481],{},"github_key.pub",[53,5483,5484,5485,5488,5489,1574,5492,5495],{},"You can reuse an existing matching pair only if it is ",[2572,5486,5487],{},"NOT"," a default key such as ",[39,5490,5491],{},"id_ed25519",[39,5493,5494],{},"id_rsa",". Otherwise, create a GitHub-specific key in the next step",[11,5497,5499,5503,5505,5509,5511,5514],{"id":5498,"level":14},"step-4-create-key-if-needed",[16,5500,5502],{"id":5501},"step-5-create-ssh-key-if-needed","Step 5: Create SSH Key If Needed",[53,5504,2298],{},[1533,5506],{"label":5507,"language":1535,"src":5508},"create-github-key.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-4-create-ssh-key-if-needed-05.sh",[53,5510,5469],{},[1533,5512],{"label":5331,"language":4948,"src":5513},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-06.txt",[20,5515,5516,5542,5547,5552],{},[23,5517,5518,5519],{},"Command flags:\n",[20,5520,5521,5527,5533],{},[23,5522,5523,5526],{},[39,5524,5525],{},"-t"," chooses the key type",[23,5528,5529,5532],{},[39,5530,5531],{},"-C"," adds a comment label, usually your GitHub email",[23,5534,5535,5537,5538,5541],{},[39,5536,3904],{}," chooses the output file path (must include ",[39,5539,5540],{},"~\u002F.ssh\u002F"," followed by the file name)",[23,5543,5544,5546],{},[39,5545,5478],{}," is the private key file",[23,5548,5549,5551],{},[39,5550,5481],{}," is the public key file for GitHub",[23,5553,5554,5555],{},"Passphrase is optional unless your instructor requires one\n",[20,5556,5557,5560],{},[23,5558,5559],{},"Pro: protects the key if someone gets the file",[23,5561,5562],{},"Con: adds an unlock prompt when the key is used",[11,5564,5566,5570,5587,5619],{"id":5565,"level":14},"step-5-start-agent-and-add-key",[16,5567,5569],{"id":5568},"step-6-start-ssh-agent-and-verify-key","Step 6: Start SSH Agent And Verify Key",[270,5571,5572,5580],{"gap":272,"left-width":1591,"right-width":1592},[277,5573,5574,5576],{"v-slot:left":279},[53,5575,2298],{},[1533,5577],{"label":5578,"language":1535,"src":5579},"start-agent-add-key.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-5-start-ssh-agent-and-add-key-07.sh",[277,5581,5582,5584],{"v-slot:right":279},[53,5583,5469],{},[1533,5585],{"label":5331,"language":4948,"src":5586},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-08.txt",[20,5588,5589,5595,5616],{},[23,5590,5591,5594],{},[39,5592,5593],{},"eval \"$(ssh-agent -s)\""," starts the SSH helper GitHub docs usually show",[23,5596,5597,5598,5601,5602,5605],{},"If that fails, run ",[39,5599,5600],{},"exec ssh-agent bash",", then run ",[39,5603,5604],{},"ssh-add ~\u002F.ssh\u002Fgithub_key",[20,5606,5607],{},[23,5608,547,5609,5612,5613,5615],{},[39,5610,5611],{},"~\u002F.ssh\u002Fgithub_key"," because ",[39,5614,3535],{}," avoids issues with spaces in home directory paths",[23,5617,5618],{},"Then verify the key is loaded",[270,5620,5621,5629],{"gap":272,"left-width":1592,"right-width":1592},[277,5622,5623,5625],{"v-slot:left":279},[53,5624,2298],{},[1533,5626],{"label":5627,"language":1535,"src":5628},"verify-loaded-key.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fverify-loaded-key-09.sh",[277,5630,5631,5633,5636],{"v-slot:right":279},[53,5632,4945],{},[1533,5634],{"label":5331,"language":4948,"src":5635},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-10.txt",[53,5637,5638],{},"One loaded key is enough for this lesson",[11,5640,5642,5646,5663],{"id":5641,"level":14},"step-6-copy-public-key",[16,5643,5645],{"id":5644},"step-7-copy-public-key","Step 7: Copy Public Key",[270,5647,5648,5656],{"gap":272,"left-width":1592,"right-width":1592},[277,5649,5650,5652],{"v-slot:left":279},[53,5651,2298],{},[1533,5653],{"label":5654,"language":1535,"src":5655},"show-public-key.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-6-copy-public-key-11.sh",[277,5657,5658,5660],{"v-slot:right":279},[53,5659,5469],{},[1533,5661],{"label":5331,"language":4948,"src":5662},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-12.txt",[20,5664,5665,5675],{},[23,5666,5667,5668,5671,5672,5674],{},"Copy the full line starting with ",[39,5669,5670],{},"ssh-ed25519"," and ending with the value you set with ",[39,5673,5531],{}," earlier",[23,5676,5677,5678,5680],{},"Do not copy ",[39,5679,5478],{},", which is the private key (never share the private key)",[11,5682,5684,5688],{"id":5683,"level":14},"step-7-add-key-to-github",[16,5685,5687],{"id":5686},"step-8-add-key-to-github","Step 8: Add Key To GitHub",[20,5689,5690,5693,5698,5701,5704],{},[23,5691,5692],{},"In GitHub, open account settings",[23,5694,4412,5695],{},[39,5696,5697],{},"SSH and GPG keys",[23,5699,5700],{},"Add a new authentication key",[23,5702,5703],{},"Paste the public key from the previous step",[23,5705,5706],{},"See the slides below for the GitHub screens",[11,5708,5710,5714],{"id":5709,"level":265},"step-8-open-github-settings",[2565,5711,5713],{"id":5712},"open-github-settings","Open GitHub Settings",[270,5715,5716,5724],{"gap":272,"left-width":1591,"right-width":274,"stack":275},[277,5717,5718],{"v-slot:left":279},[53,5719,5720],{},[283,5721],{"alt":5722,"src":5723,"variant":287},"GitHub profile menu with Settings highlighted","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-01-gh-menu.png",[277,5725,5726],{"v-slot:right":279},[20,5727,5728,5731,5736],{},[23,5729,5730],{},"Click your GitHub profile photo",[23,5732,889,5733],{},[39,5734,5735],{},"Settings",[23,5737,5738],{},"Use the account menu, not the repository settings",[11,5740,5742,5746],{"id":5741,"level":265},"step-8-open-ssh-keys-page",[2565,5743,5745],{"id":5744},"open-ssh-and-gpg-keys","Open SSH And GPG Keys",[270,5747,5748,5756],{"gap":272,"left-width":1591,"right-width":274,"stack":275},[277,5749,5750],{"v-slot:left":279},[53,5751,5752],{},[283,5753],{"alt":5754,"src":5755,"variant":287},"GitHub settings sidebar with SSH and GPG keys selected","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-02-gh-ssh-link.png",[277,5757,5758],{"v-slot:right":279},[20,5759,5760,5767,5772],{},[23,5761,5762,5763,5766],{},"Find the ",[39,5764,5765],{},"Access"," section",[23,5768,5769,5770],{},"Open ",[39,5771,5697],{},[23,5773,889,5774],{},[39,5775,5776],{},"New SSH key",[11,5778,5780,5784],{"id":5779,"level":265},"step-8-add-new-ssh-key",[2565,5781,5783],{"id":5782},"add-new-ssh-key","Add New SSH Key",[270,5785,5787,5795],{"gap":272,"left-width":5786,"right-width":4935,"stack":275},"1.35fr",[277,5788,5789],{"v-slot:left":279},[53,5790,5791],{},[283,5792],{"alt":5793,"src":5794,"variant":287},"GitHub Add new SSH Key form with title, authentication key type, and public key field","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-03-add-new-key.png",[277,5796,5797],{"v-slot:right":279},[20,5798,5799,5805,5811,5814,5819],{},[23,5800,5801,5802],{},"Title it clearly, such as ",[39,5803,5804],{},"\u003Ccourse> Laptop",[23,5806,5807,5808],{},"Keep key type as ",[39,5809,5810],{},"Authentication Key",[23,5812,5813],{},"Paste the full public key line",[23,5815,774,5816],{},[39,5817,5818],{},"Add SSH key",[23,5820,5821],{},"Never paste the private key",[11,5823,5825,5829],{"id":5824,"level":14},"step-8-test-auth",[16,5826,5828],{"id":5827},"step-9-test-github-ssh-access","Step 9: Test GitHub SSH Access",[270,5830,5831,5845],{"gap":272,"left-width":1592,"right-width":1591},[277,5832,5833,5835,5839],{"v-slot:left":279},[53,5834,2298],{},[1533,5836],{"label":5837,"language":1535,"src":5838},"test-github-ssh.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-8-test-github-ssh-access-13.sh",[53,5840,5841,5842,5844],{},"If prompted the first time, type ",[39,5843,1558],{}," to trust GitHub's host key",[277,5846,5847,5849,5852],{"v-slot:right":279},[53,5848,4945],{},[1533,5850],{"label":5331,"language":4948,"src":5851},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-14.txt",[53,5853,5854],{},"This confirms authentication, then GitHub closes the connection",[11,5856,5858,5862],{"id":5857,"level":14},"step-9-clone-repo",[16,5859,5861],{"id":5860},"step-10-clone-course-repository","Step 10: Clone Course Repository",[270,5863,5864,5905],{"gap":272,"left-width":274,"right-width":1591},[277,5865,5866,5870,5899],{"v-slot:left":279},[2565,5867,5869],{"id":5868},"get-the-ssh-clone-url","Get The SSH Clone URL",[20,5871,5872,5878,5885,5892],{},[23,5873,5874,5875],{},"In your GitHub repository, click ",[39,5876,5877],{},"Code",[23,5879,5880,5881,5884],{},"Choose the ",[39,5882,5883],{},"SSH"," tab",[23,5886,5887,5888,5891],{},"Copy the ",[39,5889,5890],{},"git@github.com:..."," link",[23,5893,5894,5895,5898],{},"Use that link in the ",[39,5896,5897],{},"git clone"," command",[53,5900,5901],{},[283,5902],{"alt":5903,"src":5904,"variant":287},"GitHub repository Code menu with SSH clone URL selected","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fgithub-clone-url.png",[277,5906,5907,5910,5914],{"v-slot:right":279},[53,5908,5909],{},"Run from the folder that should contain your course repo:",[1533,5911],{"label":5912,"language":1535,"src":5913},"clone-course-repository.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-9-clone-course-repository-15.sh",[124,5915,5916],{"type":126},[53,5917,5918,5919,5922],{},"Before cloning, run ",[39,5920,5921],{},"git rev-parse --show-toplevel",". If it prints a path, move somewhere else first. Clone this repo only once.",[53,5924,5469],{},[1533,5926],{"label":5331,"language":4948,"src":5927},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-16.txt",[53,5929,5930,5931,5934,5935,5938],{},"If you see an empty repository warning, you probably forgot to add ",[39,5932,5933],{},"README.md"," when creating the repo. Create it with ",[39,5936,5937],{},"touch README.md",", then use the add\u002Fcommit\u002Fpush commands from the next lesson\n::\n::",[11,5940,5942,5946,5965,5984,6004],{"id":5941,"level":14},"step-10-set-repo-identity",[16,5943,5945],{"id":5944},"step-11-set-repo-git-identity","Step 11: Set Repo Git Identity",[270,5947,5948,5957],{"gap":272,"left-width":1592,"right-width":1592},[277,5949,5950,5953],{"v-slot:left":279},[53,5951,5952],{},"Run inside the cloned repository:",[1533,5954],{"label":5955,"language":1535,"src":5956},"set-repo-identity.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-10-set-repo-git-identity-17.sh",[277,5958,5959,5961],{"v-slot:right":279},[53,5960,4945],{},[1533,5962],{"label":5963,"language":4948,"src":5964},"config-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-19.txt",[270,5966,5967,5976],{"gap":272,"left-width":1592,"right-width":1592},[277,5968,5969,5972],{"v-slot:left":279},[53,5970,5971],{},"Then verify:",[1533,5973],{"label":5974,"language":1535,"src":5975},"verify-repo-identity.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-10-set-repo-git-identity-18.sh",[277,5977,5978,5980],{"v-slot:right":279},[53,5979,4945],{},[1533,5981],{"label":5982,"language":4948,"src":5983},"identity-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-20.txt",[20,5985,5986,5992,5998],{},[23,5987,5988,5991],{},[39,5989,5990],{},"user.name"," can be your real or display name, though commonly it's your GitHub username",[23,5993,5994,5997],{},[39,5995,5996],{},"user.email"," should match a GitHub email or GitHub no-reply address for commit linking to work (this is important)",[23,5999,6000,6003],{},[39,6001,6002],{},"core.sshCommand"," tells this repository to use your course GitHub key",[53,6005,6006,6007,6010],{},"These commands set identity for this repository. The ",[39,6008,6009],{},"--global"," flag is an option only if you intentionally want the same identity for all repositories",[11,6012,6014,6018,6021,6037],{"id":6013,"level":14},"step-11-invite-collaborators",[16,6015,6017],{"id":6016},"step-12-invite-course-collaborators","Step 12: Invite Course Collaborators",[53,6019,6020],{},"In GitHub, open your course repository:",[20,6022,6023,6026,6031,6034],{},[23,6024,6025],{},"Settings -> Collaborators and teams",[23,6027,6028,6029],{},"Invite ",[39,6030,3139],{},[23,6032,6033],{},"Invite your TA if your section has one",[23,6035,6036],{},"Wait until the invitation shows as sent or accepted",[53,6038,6039],{},"This is so it can be accessed for grading and assistance",[11,6041,6043,6046],{"id":6042,"level":14},"troubleshooting-auth",[16,6044,6045],{"id":6042},"Troubleshooting Auth",[20,6047,6048,6054,6061,6068,6071],{},[23,6049,6050,6053],{},[39,6051,6052],{},"Permission denied (publickey)",": GitHub did not accept a loaded key",[23,6055,6056,6057,6060],{},"No loaded key in ",[39,6058,6059],{},"ssh-add -l",": start the agent and add the key again",[23,6062,6063,6064,6067],{},"Wrong key in GitHub: delete it and paste the ",[39,6065,6066],{},".pub"," key again",[23,6069,6070],{},"Wrong account: make sure the success message names your GitHub account",[23,6072,6073],{},"See the slide below for a quick reset sequence",[11,6075,6077,6081,6083,6110],{"id":6076,"level":265},"troubleshooting-auth-recovery",[2565,6078,6080],{"id":6079},"quick-reset-sequence","Quick Reset Sequence",[53,6082,2298],{},[2491,6084,6085,6089,6093,6097,6102,6105],{},[23,6086,6087],{},[39,6088,5593],{},[23,6090,6091],{},[39,6092,5604],{},[23,6094,6095],{},[39,6096,6059],{},[23,6098,6099],{},[39,6100,6101],{},"cat ~\u002F.ssh\u002Fgithub_key.pub",[23,6103,6104],{},"Re-paste the public key in GitHub if needed",[23,6106,6107],{},[39,6108,6109],{},"ssh -T git@github.com",[53,6111,1629,6112,6114,6115,6117,6118,6121],{},[39,6113,5593],{}," fails in Git Bash, use ",[39,6116,5600],{},", then repeat the ",[39,6119,6120],{},"ssh-add"," steps",[11,6123,6124,6126,6129],{"id":3197,"level":14},[16,6125,3200],{"id":3197},[53,6127,6128],{},"You are done when all are true:",[20,6130,6131,6136,6143,6148,6151,6156,6159],{},[23,6132,6133,6135],{},[39,6134,4366],{}," works",[23,6137,6138,6140,6141],{},[39,6139,6059],{}," shows ",[39,6142,5478],{},[23,6144,6145,6147],{},[39,6146,6109],{}," names your GitHub account",[23,6149,6150],{},"Your private course repository exists on GitHub",[23,6152,6153,6155],{},[39,6154,3139],{}," and your TA, if applicable, are invited as collaborators",[23,6157,6158],{},"Your local terminal is open to the cloned repository",[23,6160,6161,1732,6164,6167],{},[39,6162,6163],{},"git config user.name",[39,6165,6166],{},"git config user.email"," return your repo identity",[11,6169,6170,6172],{"id":2611,"level":14},[16,6171,2559],{"id":2556},[270,6173,6174,6202],{"gap":272,"left-width":1592,"right-width":1592},[277,6175,6176,6178,6184,6190,6196],{"v-slot:left":279},[2565,6177,2568],{"id":2567},[53,6179,6180,6183],{},[2572,6181,6182],{},"Git identity"," - commit name and email saved in repo config",[53,6185,6186,6189],{},[2572,6187,6188],{},"SSH key pair"," - private key on your computer, public key in GitHub",[53,6191,6192,6195],{},[2572,6193,6194],{},"SSH agent"," - background helper that makes your private key available",[53,6197,6198,6201],{},[2572,6199,6200],{},"Clone"," - local copy of a GitHub repository",[277,6203,6204,6206],{"v-slot:right":279},[2565,6205,2612],{"id":2611},[20,6207,6208,6215,6222,6229],{},[23,6209,6210],{},[146,6211,6214],{"href":6212,"rel":6213},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fauthentication\u002Fconnecting-to-github-with-ssh\u002Fgenerating-a-new-ssh-key-and-adding-it-to-the-ssh-agent",[150],"GitHub Docs: Generate a new SSH key and add it to the ssh-agent",[23,6216,6217],{},[146,6218,6221],{"href":6219,"rel":6220},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fauthentication\u002Fconnecting-to-github-with-ssh\u002Ftesting-your-ssh-connection",[150],"GitHub Docs: Testing your SSH connection",[23,6223,6224],{},[146,6225,6228],{"href":6226,"rel":6227},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fcreating-and-managing-repositories\u002Fcreating-a-new-repository",[150],"GitHub Docs: Create a repository",[23,6230,6231],{},[146,6232,6235],{"href":6233,"rel":6234},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fcreating-and-managing-repositories\u002Fcloning-a-repository",[150],"GitHub Docs: Cloning a repository",[11,6237,6238,6240,6242],{"id":2664,"level":14},[16,6239,2667],{"id":2664},[53,6241,2670],{},[20,6243,6244,6247,6250,6253,6256,6259,6265],{},[23,6245,6246],{},"Use the correct terminal for your operating system",[23,6248,6249],{},"Authenticate to GitHub with SSH",[23,6251,6252],{},"Find your private course repository on GitHub",[23,6254,6255],{},"Invite course collaborators",[23,6257,6258],{},"Open the local clone in the terminal",[23,6260,6261,6262],{},"Show repo-local Git identity with ",[39,6263,6264],{},"git config",[23,6266,6267],{},"Next: practice the Git commands used for course work",{"title":279,"searchDepth":2694,"depth":2694,"links":6269},[6270,6271,6272,6273,6274,6275,6276,6277,6278,6279,6280,6281,6286,6287,6288,6289,6290,6293,6294,6295],{"id":5229,"depth":2694,"text":5232},{"id":5255,"depth":2694,"text":5258},{"id":5273,"depth":2694,"text":5276},{"id":5298,"depth":2694,"text":5301},{"id":5311,"depth":2694,"text":5314},{"id":5341,"depth":2694,"text":5342},{"id":5378,"depth":2694,"text":5379},{"id":5453,"depth":2694,"text":5454},{"id":5501,"depth":2694,"text":5502},{"id":5568,"depth":2694,"text":5569},{"id":5644,"depth":2694,"text":5645},{"id":5686,"depth":2694,"text":5687,"children":6282},[6283,6284,6285],{"id":5712,"depth":3262,"text":5713},{"id":5744,"depth":3262,"text":5745},{"id":5782,"depth":3262,"text":5783},{"id":5827,"depth":2694,"text":5828},{"id":5860,"depth":2694,"text":5861},{"id":5944,"depth":2694,"text":5945},{"id":6016,"depth":2694,"text":6017},{"id":6042,"depth":2694,"text":6045,"children":6291},[6292],{"id":6079,"depth":3262,"text":6080},{"id":3197,"depth":2694,"text":3200},{"id":2556,"depth":2694,"text":2559},{"id":2664,"depth":2694,"text":2667},"Connect your computer to GitHub with SSH, create the course repository, clone it, and set repo-local Git identity.","Face-to-face class of about 40 students; includes GitHub account check, SSH key generation, GitHub UI steps, repo creation, clone troubleshooting, repo-local Git identity, and authentication checks.","15","70","85",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh",{"title":5224,"description":6296},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh",[4554,6306,796,6307],"github","repository","48:26","HZG3_HfczOk","https:\u002F\u002Fyoutu.be\u002FHZG3_HfczOk","Setup Git SSH and GitHub","rJ2RP6nrPEoOj98kzeevFpO0YOXaJl-M5ajP_tsjwvA",{"id":6314,"title":6315,"audience":6,"body":6316,"contentType":2762,"course":2763,"description":7234,"estimateBasis":7235,"estimatedDiscussionMinutes":3269,"estimatedLiveMinutes":6299,"estimatedTotalMinutes":2771,"extension":871,"meta":7236,"module":569,"navigation":2770,"order":7237,"path":7238,"promptAssist":2773,"seo":7239,"status":2775,"stem":7240,"tags":7241,"videoDuration":7244,"videoId":7245,"videoLink":7246,"videoTitle":7247,"week":569,"__hash__":7248},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs.md","Git Commands And Pull Requests",{"type":8,"value":6317,"toc":7199},[6318,6347,6368,6384,6416,6450,6501,6517,6538,6569,6601,6643,6674,6709,6733,6778,6805,6835,6853,6865,6901,6934,6970,7004,7029,7057,7087,7154,7196],[11,6319,6321,6324,6327],{"id":6320,"level":14},"objectives",[16,6322,6323],{"id":6320},"Objectives",[53,6325,6326],{},"By the end, you should be able to:",[20,6328,6329,6332,6335,6338,6341,6344],{},[23,6330,6331],{},"Explain what the common Git commands do",[23,6333,6334],{},"Connect commands to the working folder, staging area, local commits, and GitHub remote",[23,6336,6337],{},"Create a branch for practice work",[23,6339,6340],{},"Stage, commit, and push a small change",[23,6342,6343],{},"Open a pull request on GitHub",[23,6345,6346],{},"Investigate a failed push and a merge conflict",[11,6348,6350,6354,6357,6360],{"id":6349,"level":14},"git-vs-github",[16,6351,6353],{"id":6352},"git-versus-github","Git Versus GitHub",[53,6355,6356],{},"Git is the tool that tracks file history",[53,6358,6359],{},"GitHub is a website that hosts a remote copy of a Git repository",[20,6361,6362,6365],{},[23,6363,6364],{},"Git: local terminal workflow",[23,6366,6367],{},"GitHub: remote branches, pull requests, issues, and project evidence",[11,6369,6371,6375,6378,6381],{"id":6370,"level":14},"git-stages",[16,6372,6374],{"id":6373},"the-git-stages","The Git Stages",[1533,6376],{"language":1542,"src":6377},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fthe-git-stages-01.txt",[53,6379,6380],{},"Common commands:",[1533,6382],{"language":1542,"src":6383},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fthe-git-stages-02.txt",[11,6385,6387,6391,6393,6396,6399,6402],{"id":6386,"level":14},"status-first",[16,6388,6390],{"id":6389},"command-1-git-status","Command 1: git status",[53,6392,2298],{},[1533,6394],{"language":1535,"src":6395},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-1-git-status-03.sh",[53,6397,6398],{},"Use this before and after every important Git action",[53,6400,6401],{},"It tells you:",[20,6403,6404,6407,6410,6413],{},[23,6405,6406],{},"Current branch",[23,6408,6409],{},"Changed files",[23,6411,6412],{},"Staged files",[23,6414,6415],{},"Whether your working tree is clean",[11,6417,6419,6423,6425,6428],{"id":6418,"level":14},"branch-command",[16,6420,6422],{"id":6421},"command-2-git-branch","Command 2: git branch",[53,6424,2298],{},[1533,6426],{"language":1535,"src":6427},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-2-git-branch-04.sh",[20,6429,6430,6433,6436],{},[23,6431,6432],{},"Active branch has an asterisk",[23,6434,6435],{},"Branches are separate timelines for work",[23,6437,6438,6439],{},"Branch names are case-sensitive\n",[20,6440,6441],{},[23,6442,6443,1732,6446,6449],{},[39,6444,6445],{},"Practice",[39,6447,6448],{},"practice"," are different names",[11,6451,6453,6457,6462,6465],{"id":6452,"level":14},"create-branch",[16,6454,6456],{"id":6455},"practice-step-1-create-a-branch","Practice Step 1: Create A Branch",[53,6458,6459,6460,2078],{},"Start from ",[39,6461,4519],{},[1533,6463],{"language":1535,"src":6464},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpractice-step-1-create-a-05.sh",[20,6466,6467,6478],{},[23,6468,6469,6470,6472,6473],{},"First two commands: make sure ",[39,6471,4519],{}," is current\n",[20,6474,6475],{},[23,6476,6477],{},"Explained more later",[23,6479,6480,6481],{},"Branch control commands\n",[20,6482,6483,6489,6495],{},[23,6484,6485,6488],{},[39,6486,6487],{},"git checkout -b practice",": create and switch",[23,6490,6491,6494],{},[39,6492,6493],{},"git branch practice",": create only",[23,6496,6497,6500],{},[39,6498,6499],{},"git checkout practice",": switch to existing",[11,6502,6504,6508,6511,6514],{"id":6503,"level":14},"make-file",[16,6505,6507],{"id":6506},"practice-step-2-make-a-small-file","Practice Step 2: Make A Small File",[53,6509,6510],{},"Create a small practice file:",[1533,6512],{"language":1535,"src":6513},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpractice-step-2-make-a-s-06.sh",[53,6515,6516],{},"Expected result: Git shows the new file as untracked",[11,6518,6520,6524,6527,6530,6533],{"id":6519,"level":14},"add-command",[16,6521,6523],{"id":6522},"command-3-git-add","Command 3: git add",[53,6525,6526],{},"Stage the new file:",[1533,6528],{"language":1535,"src":6529},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-3-git-add-07.sh",[53,6531,6532],{},"Staging means: include this change in the next commit",[20,6534,6535],{},[23,6536,6537],{},"See below for add patterns and verification checks",[11,6539,6541,6545,6548,6551],{"id":6540,"level":265},"add-variants",[2565,6542,6544],{"id":6543},"common-git-add-patterns","Common git add Patterns",[53,6546,6547],{},"Use the smallest clear target when possible",[1533,6549],{"language":1535,"src":6550},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommon-git-add-patterns-08.sh",[20,6552,6553,6556,6559],{},[23,6554,6555],{},"Single file: safest when you changed one file",[23,6557,6558],{},"Folder: useful when one feature is grouped in one folder",[23,6560,6561,6564,6565,6568],{},[39,6562,6563],{},"git add .",": convenient, but review ",[39,6566,6567],{},"git status"," first",[11,6570,6572,6576,6579,6582],{"id":6571,"level":14},"diff-command",[16,6573,6575],{"id":6574},"command-4-git-diff","Command 4: git diff",[53,6577,6578],{},"Before committing, inspect what changed:",[1533,6580],{"language":1535,"src":6581},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-4-git-diff-09.sh",[20,6583,6584,6591,6594,6599],{},[23,6585,6586,6587,6590],{},"New untracked file: ",[39,6588,6589],{},"git diff"," may show nothing",[23,6592,6593],{},"That does not mean the file is missing",[23,6595,547,6596,6598],{},[39,6597,6567],{}," to confirm untracked files",[23,6600,4055],{},[11,6602,6604,6608,6611,6614,6617,6620],{"id":6603,"level":265},"cached-rm",[2565,6605,6607],{"id":6606},"if-you-staged-the-wrong-file","If You Staged The Wrong File",[53,6609,6610],{},"If a file was staged by mistake, remove it from staging:",[1533,6612],{"language":1535,"src":6613},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fif-you-staged-the-wrong--10.sh",[53,6615,6616],{},"For a folder:",[1533,6618],{"language":1535,"src":6619},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fif-you-staged-the-wrong--11.sh",[20,6621,6622,6633],{},[23,6623,6624,6627,6628],{},[39,6625,6626],{},"--cached",": remove from staging only\n",[20,6629,6630],{},[23,6631,6632],{},"Keeps the file in your working folder",[23,6634,6635,6637,6638],{},[39,6636,3374],{},": folder mode\n",[20,6639,6640],{},[23,6641,6642],{},"Recursive: include files inside the folder",[11,6644,6646,6650,6653,6656,6659],{"id":6645,"level":14},"commit-command",[16,6647,6649],{"id":6648},"command-5-git-commit","Command 5: git commit",[53,6651,6652],{},"Commit the staged file:",[1533,6654],{"language":1535,"src":6655},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-5-git-commit-12.sh",[53,6657,6658],{},"A commit is a saved checkpoint in your local repository",[20,6660,6661,6672],{},[23,6662,6663,6666,6667],{},[39,6664,6665],{},"-m",": commit message",[20,6668,6669],{},[23,6670,6671],{},"Required, even if the message is an empty string",[23,6673,4055],{},[11,6675,6677,6681,6683,6686,6706],{"id":6676,"level":265},"log-command",[2565,6678,6680],{"id":6679},"check-the-local-history","Check The Local History",[53,6682,2298],{},[1533,6684],{"language":1535,"src":6685},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcheck-the-local-history-13.sh",[20,6687,6688,6694,6700],{},[23,6689,6690,6693],{},[39,6691,6692],{},"log",": show commit history",[23,6695,6696,6699],{},[39,6697,6698],{},"--oneline",": one commit per line",[23,6701,6702,6705],{},[39,6703,6704],{},"-5",": show the latest five commits",[53,6707,6708],{},"You should see your latest commit near the top",[11,6710,6712,6716,6719,6722],{"id":6711,"level":14},"push-command",[16,6713,6715],{"id":6714},"command-6-git-push","Command 6: git push",[53,6717,6718],{},"Send the branch to GitHub:",[1533,6720],{"language":1535,"src":6721},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-6-git-push-14.sh",[20,6723,6724,6730],{},[23,6725,6726,6729],{},[39,6727,6728],{},"origin",": common remote name for GitHub",[23,6731,6732],{},"Final part: branch you are pushing",[11,6734,6736,6740],{"id":6735,"level":14},"open-pr",[16,6737,6739],{"id":6738},"pull-request","Pull Request",[270,6741,6742,6770],{"gap":272,"left-width":1592,"right-width":1592},[277,6743,6744,6747,6750,6753,6756,6759],{"v-slot:left":279},[53,6745,6746],{},"On GitHub, open a pull request",[53,6748,6749],{},"Use this direction:",[1533,6751],{"language":1542,"src":6752},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-request-15.txt",[53,6754,6755],{},"Use a clear description:",[1533,6757],{"language":1542,"src":6758},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-request-description-16.txt",[20,6760,6761,6764,6767],{},[23,6762,6763],{},"Review page before merge",[23,6765,6766],{},"Shows what will change",[23,6768,6769],{},"Captures branch evidence",[277,6771,6772],{"v-slot:right":279},[53,6773,6774],{},[283,6775],{"alt":6776,"src":6777,"variant":287},"GitHub pull request creation page showing base main and compare practice","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgithub-create-pull-request.png",[11,6779,6781,6785,6788,6796,6799,6802],{"id":6780,"level":14},"merge-pr",[16,6782,6784],{"id":6783},"merge-and-sync","Merge And Sync",[53,6786,6787],{},"After GitHub merge:",[20,6789,6790],{},[23,6791,6792,6793,6795],{},"Local ",[39,6794,4519],{}," is not updated automatically",[53,6797,6798],{},"Sync it:",[1533,6800],{"language":1535,"src":6801},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fmerge-and-sync-15.sh",[53,6803,6804],{},"Remote changes must be pulled down intentionally",[11,6806,6808,6812,6815,6832],{"id":6807,"level":14},"why-prs",[16,6809,6811],{"id":6810},"why-pull-requests-matter","Why Pull Requests Matter",[53,6813,6814],{},"Pull requests create evidence:",[20,6816,6817,6820,6823,6826,6829],{},[23,6818,6819],{},"Which branch changed",[23,6821,6822],{},"Which files changed",[23,6824,6825],{},"What discussion or explanation was provided",[23,6827,6828],{},"Chance to review risky changes before merging",[23,6830,6831],{},"When the change was merged",[53,6833,6834],{},"For this course, pull requests are part of the workflow evidence, not just a GitHub feature",[11,6836,6838,6842,6845],{"id":6837,"level":14},"exploration-intro",[16,6839,6841],{"id":6840},"troubleshooting-explorations","Troubleshooting Explorations",[53,6843,6844],{},"The next slides use controlled problems to practice recovery",[20,6846,6847,6850],{},[23,6848,6849],{},"The goal is not avoiding every error",[23,6851,6852],{},"The goal is reading output, identifying state, and recovering without guessing",[11,6854,6856,6859,6862],{"id":6855,"level":14},"exploration-setup",[16,6857,6858],{"id":6855},"Exploration Setup",[53,6860,6861],{},"Create a conflict practice branch:",[1533,6863],{"language":1535,"src":6864},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-setup-16.sh",[11,6866,6868,6872,6878,6885,6890,6893,6896],{"id":6867,"level":14},"exploration-issue-1",[16,6869,6871],{"id":6870},"exploration-issue-1-push-rejected","Exploration Issue 1: Push Rejected",[53,6873,6874,6875],{},"On GitHub, switch to ",[39,6876,6877],{},"practice-conflict",[53,6879,6880,6881,6884],{},"Edit one line in ",[39,6882,6883],{},"myFile.txt"," directly on GitHub and commit the change",[20,6886,6887],{},[23,6888,6889],{},"Use the same line you will change locally",[53,6891,6892],{},"Back locally, edit that same line and commit:",[1533,6894],{"language":1535,"src":6895},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-issue-1-push-17.sh",[20,6897,6898],{},[23,6899,6900],{},"See the slides below for the rejected push and the pull that creates the conflict",[11,6902,6904,6908,6911],{"id":6903,"level":265},"issue-1-push-without-pulling",[2565,6905,6907],{"id":6906},"try-push-without-pulling","Try Push Without Pulling",[53,6909,6910],{},"Push the local commit before pulling the GitHub commit:",[270,6912,6913,6926],{"gap":272,"left-width":1592,"right-width":1592},[277,6914,6915,6918],{"v-slot:left":279},[1533,6916],{"language":1535,"src":6917},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Ftry-push-without-pulling-20.sh",[20,6919,6920,6923],{},[23,6921,6922],{},"Expected result: push rejected",[23,6924,6925],{},"Reason: GitHub has a commit your local branch does not have",[277,6927,6928],{"v-slot:right":279},[53,6929,6930],{},[283,6931],{"alt":6932,"src":6933,"variant":287},"Git push rejected because the remote branch has commits that are not local yet","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgit-push-rejected-before-pull.png",[11,6935,6937,6941],{"id":6936,"level":265},"issue-1-read-output",[2565,6938,6940],{"id":6939},"pull-the-remote-change","Pull The Remote Change",[270,6942,6943,6962],{"gap":272,"left-width":1592,"right-width":1592},[277,6944,6945,6948,6951,6954,6959],{"v-slot:left":279},[53,6946,6947],{},"The usual next command is:",[1533,6949],{"language":1535,"src":6950},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-the-remote-change-20.sh",[53,6952,6953],{},"If Git asks how to reconcile divergent branches:",[20,6955,6956],{},[23,6957,6958],{},"Use merge behavior for this course practice",[1533,6960],{"language":1535,"src":6961},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-the-remote-change-21.sh",[277,6963,6964],{"v-slot:right":279},[53,6965,6966],{},[283,6967],{"alt":6968,"src":6969,"variant":287},"Git pull output asking how to reconcile divergent branches","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgit-pull-divergent-branches.png",[11,6971,6973,6977,6980,6984,6987,6990,6993],{"id":6972,"level":14},"exploration-issue-2",[16,6974,6976],{"id":6975},"exploration-issue-2-merge-conflict","Exploration Issue 2: Merge Conflict",[53,6978,6979],{},"After pulling, Git should report a conflict",[53,6981,5769,6982],{},[39,6983,6883],{},[53,6985,6986],{},"You may see markers like:",[1533,6988],{"language":1542,"src":6989},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-issue-2-merg-18.txt",[53,6991,6992],{},"Conflict markers show:",[20,6994,6995,6998,7001],{},[23,6996,6997],{},"Your local version",[23,6999,7000],{},"The GitHub version",[23,7002,7003],{},"The part Git could not combine automatically",[11,7005,7007,7011,7017,7020,7022,7025],{"id":7006,"level":265},"resolve-conflict",[2565,7008,7010],{"id":7009},"resolve-the-conflict","Resolve The Conflict",[53,7012,7013,7014,7016],{},"Edit ",[39,7015,6883],{}," so it contains the final text you want",[53,7018,7019],{},"Remove all conflict markers",[53,7021,2224],{},[1533,7023],{"language":1535,"src":7024},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fresolve-the-conflict-19.sh",[20,7026,7027],{},[23,7028,4055],{},[11,7030,7032,7036,7039],{"id":7031,"level":265},"verify-conflict-resolution",[2565,7033,7035],{"id":7034},"verify-the-recovery","Verify The Recovery",[53,7037,7038],{},"Check:",[20,7040,7041,7046,7049,7054],{},[23,7042,7043,7045],{},[39,7044,6567],{}," is clean",[23,7047,7048],{},"GitHub shows the updated branch",[23,7050,7051,7053],{},[39,7052,6883],{}," contains the final text",[23,7055,7056],{},"No conflict markers remain",[11,7058,7059,7061],{"id":4107,"level":14},[16,7060,4110],{"id":4107},[20,7062,7063,7066,7069,7072,7075,7084],{},[23,7064,7065],{},"Committing on the wrong branch",[23,7067,7068],{},"Forgetting to push after committing",[23,7070,7071],{},"Forgetting to pull after merging on GitHub",[23,7073,7074],{},"Leaving conflict markers in a file",[23,7076,7077,7078,1574,7081],{},"Using vague branch names like ",[39,7079,7080],{},"stuff",[39,7082,7083],{},"final",[23,7085,7086],{},"Making several unrelated changes in one commit",[11,7088,7089,7091],{"id":2611,"level":14},[16,7090,2559],{"id":2556},[270,7092,7093,7117],{"gap":272,"left-width":1592,"right-width":1592},[277,7094,7095,7097],{"v-slot:left":279},[2565,7096,2568],{"id":2567},[20,7098,7099,7102,7105,7108,7111,7114],{},[23,7100,7101],{},"Working folder: files you can edit",[23,7103,7104],{},"Staging area: changes selected for the next commit",[23,7106,7107],{},"Commit: local saved checkpoint",[23,7109,7110],{},"Remote: GitHub copy of the repository",[23,7112,7113],{},"Pull request: GitHub page for reviewing and merging branch work",[23,7115,7116],{},"Conflict: a change Git cannot merge automatically",[277,7118,7119,7121],{"v-slot:right":279},[2565,7120,2612],{"id":2611},[20,7122,7123,7131,7138,7146],{},[23,7124,7125,7126],{},"Pro Git Book: ",[146,7127,7130],{"href":7128,"rel":7129},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Basics-Getting-a-Git-Repository",[150],"Git Basics",[23,7132,7125,7133],{},[146,7134,7137],{"href":7135,"rel":7136},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Branching-Basic-Branching-and-Merging",[150],"Basic Branching and Merging",[23,7139,7140,7141],{},"GitHub Docs: ",[146,7142,7145],{"href":7143,"rel":7144},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpull-requests\u002Fcollaborating-with-pull-requests\u002Fproposing-changes-to-your-work-with-pull-requests\u002Fcreating-a-pull-request",[150],"Creating a pull request",[23,7147,7148,7149],{},"Oh Shit, Git!?!: ",[146,7150,7153],{"href":7151,"rel":7152},"https:\u002F\u002Fohshitgit.com\u002F",[150],"Common Git recovery situations",[11,7155,7156,7158],{"id":2664,"level":14},[16,7157,2667],{"id":2664},[270,7159,7162,7186],{"gap":871,"left-width":7160,"right-width":7161},"0.72fr","1.38fr",[277,7163,7164,7166],{"v-slot:left":279},[53,7165,2670],{},[20,7167,7168,7174,7177,7180,7183],{},[23,7169,7170,7171,7173],{},"Read ",[39,7172,6567],{}," before choosing the next command",[23,7175,7176],{},"Move a change from working folder to staging area to commit",[23,7178,7179],{},"Push a branch to GitHub and open a pull request",[23,7181,7182],{},"Recognize when a failed push or conflict needs recovery",[23,7184,7185],{},"Next: open the cloned repository in VS Code",[277,7187,7188,7191],{"v-slot:right":279},[53,7189,7190],{},"Git\u002FGitHub flow:",[7192,7193],"figure-image",{"alt":7194,"src":7195},"Lane diagram showing local Git commands moving from the base branch to a feature or homework branch, then pushing to GitHub for pull request review and merge, then pulling the base branch back locally","\u002Fimages\u002Fshared\u002Fgit-github-lane-flow.svg",[53,7197,7198],{},"::",{"title":279,"searchDepth":2694,"depth":2694,"links":7200},[7201,7202,7203,7204,7205,7206,7207,7208,7211,7214,7217,7218,7219,7220,7221,7222,7223,7227,7231,7232,7233],{"id":6320,"depth":2694,"text":6323},{"id":6352,"depth":2694,"text":6353},{"id":6373,"depth":2694,"text":6374},{"id":6389,"depth":2694,"text":6390},{"id":6421,"depth":2694,"text":6422},{"id":6455,"depth":2694,"text":6456},{"id":6506,"depth":2694,"text":6507},{"id":6522,"depth":2694,"text":6523,"children":7209},[7210],{"id":6543,"depth":3262,"text":6544},{"id":6574,"depth":2694,"text":6575,"children":7212},[7213],{"id":6606,"depth":3262,"text":6607},{"id":6648,"depth":2694,"text":6649,"children":7215},[7216],{"id":6679,"depth":3262,"text":6680},{"id":6714,"depth":2694,"text":6715},{"id":6738,"depth":2694,"text":6739},{"id":6783,"depth":2694,"text":6784},{"id":6810,"depth":2694,"text":6811},{"id":6840,"depth":2694,"text":6841},{"id":6855,"depth":2694,"text":6858},{"id":6870,"depth":2694,"text":6871,"children":7224},[7225,7226],{"id":6906,"depth":3262,"text":6907},{"id":6939,"depth":3262,"text":6940},{"id":6975,"depth":2694,"text":6976,"children":7228},[7229,7230],{"id":7009,"depth":3262,"text":7010},{"id":7034,"depth":3262,"text":7035},{"id":4107,"depth":2694,"text":4110},{"id":2556,"depth":2694,"text":2559},{"id":2664,"depth":2694,"text":2667},"Practice the core Git workflow with small changes, branches, pull requests, and two guided troubleshooting scenarios.","Face-to-face class of about 40 students; includes command explanation, branch practice, pull request walkthrough, conflict exploration, and recovery discussion.",{},"40","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs",{"title":6315,"description":7234},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs",[4554,7242,7243],"branches","pull-requests","48:54","MOa9zIUOqaI","https:\u002F\u002Fyoutu.be\u002FMOa9zIUOqaI","Git Commands and PRs","GTIGHU5IyAE7RcRy68evvCM5YPZVDAWUbiTdBfC9nCI",{"id":7250,"title":7251,"audience":6,"body":7252,"contentType":2762,"course":2763,"description":8019,"estimateBasis":8020,"estimatedDiscussionMinutes":3268,"estimatedLiveMinutes":3270,"estimatedTotalMinutes":7237,"extension":871,"meta":8021,"module":569,"navigation":2770,"order":8022,"path":8023,"promptAssist":2773,"seo":8024,"status":2775,"stem":8025,"tags":8026,"videoDuration":8029,"videoId":8030,"videoLink":8031,"videoTitle":8032,"week":569,"__hash__":8033},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment.md","Local Development Environment Setup",{"type":8,"value":7253,"toc":7997},[7254,7271,7289,7310,7335,7370,7402,7480,7553,7654,7682,7747,7824,7848,7875,7893,7917,7968],[11,7255,7257,7260],{"id":7256,"level":14},"local-development-environment-title",[16,7258,7251],{"id":7259},"local-development-environment-setup",[20,7261,7262,7265,7268],{},[23,7263,7264],{},"VS Code for editing course files",[23,7266,7267],{},"Course profile for Internet Applications extensions",[23,7269,7270],{},"Optional local PHP check on your own computer",[11,7272,7273,7275],{"id":3351,"level":14},[16,7274,3354],{"id":3351},[20,7276,7277,7280,7283,7286],{},[23,7278,7279],{},"Install VS Code",[23,7281,7282],{},"Open the course repository root",[23,7284,7285],{},"Install the required extensions for the course",[23,7287,7288],{},"Have a local php install as a light weight dev server (as a backup for the VM lessons)",[11,7290,7292,7295],{"id":7291,"level":14},"what-this-setup-does",[16,7293,7294],{"id":7291},"What This Setup Does",[20,7296,7297,7300,7303],{},[23,7298,7299],{},"VS Code: editor for course files",[23,7301,7302],{},"Extensions: syntax help, Git visibility, database viewing, time tracking",[23,7304,7305,7306,7309],{},"Optional host PHP: quick ",[39,7307,7308],{},"php -v"," check and editor support",[11,7311,7313,7316],{"id":7312,"level":14},"step-1-install-vs-code",[16,7314,7315],{"id":7312},"Step 1: Install VS Code",[20,7317,7318,7326,7329,7332],{},[23,7319,7320,7321],{},"Download: ",[146,7322,7325],{"href":7323,"rel":7324},"https:\u002F\u002Fcode.visualstudio.com\u002FDownload",[150],"Visual Studio Code",[23,7327,7328],{},"Install like a normal desktop app",[23,7330,7331],{},"Do not install VS Code inside your repository folder",[23,7333,7334],{},"VS Code is the editor; the repo is the workspace folder",[11,7336,7338,7341,7344,7367],{"id":7337,"level":14},"step-2-open-the-repository",[16,7339,7340],{"id":7337},"Step 2: Open The Repository",[53,7342,7343],{},"After the course repo is cloned:",[20,7345,7346,7356,7359,7364],{},[23,7347,7348,7349,7352,7353],{},"VS Code -> ",[39,7350,7351],{},"File"," -> ",[39,7354,7355],{},"Open Folder",[23,7357,7358],{},"Choose the repository root",[23,7360,7361,7362],{},"Folder name should match ",[39,7363,5404],{},[23,7365,7366],{},"Trust the workspace only if it is your cloned GitHub repo",[53,7368,7369],{},"Do not open a ZIP copy or clone the same repo again",[11,7371,7373,7377,7399],{"id":7372,"level":14},"step-3-create-course-profile",[16,7374,7376],{"id":7375},"step-3-create-a-course-profile","Step 3: Create A Course Profile",[20,7378,7379,7385,7393,7396],{},[23,7380,7381,7382],{},"Gear icon -> ",[39,7383,7384],{},"Profiles",[23,7386,7387,7388,1574,7390],{},"Create ",[39,7389,2763],{},[39,7391,7392],{},"PHP",[23,7394,7395],{},"Switch into that profile",[23,7397,7398],{},"Install course extensions there",[53,7400,7401],{},"Profiles keep this course setup separate from other projects",[11,7403,7405,7408,7412],{"id":7404,"level":14},"step-4-install-extensions",[16,7406,7407],{"id":7404},"Step 4: Install Extensions",[2565,7409,7411],{"id":7410},"start-with-these","Start With These",[20,7413,7414,7422,7430,7438,7446,7454,7469,7477],{},[23,7415,7416,7417],{},"Auto Rename Tag (Jun Han)\n",[20,7418,7419],{},[23,7420,7421],{},"Auto-completes matching HTML tags while you edit",[23,7423,7424,7425],{},"Bracket Lens (wraith13)\n",[20,7426,7427],{},[23,7428,7429],{},"Adds readability cues for closing brackets",[23,7431,7432,7433],{},"GitLens (GitKraken)\n",[20,7434,7435],{},[23,7436,7437],{},"Required: Git history, blame, and branch visibility in-editor",[23,7439,7440,7441],{},"MySQL (cweijan)\n",[20,7442,7443],{},[23,7444,7445],{},"Required later: connect to and inspect course database tables",[23,7447,7448,7449],{},"PHP Intelephense (Ben Mewburn)\n",[20,7450,7451],{},[23,7452,7453],{},"PHP language support, syntax checks, and warnings",[23,7455,7456,7457],{},"Todo Tree (Gruntfuggly)\n",[20,7458,7459],{},[23,7460,7461,7462,2269,7465,7468],{},"Finds and lists ",[39,7463,7464],{},"TODO",[39,7466,7467],{},"FIXME",", and similar comments",[23,7470,7471,7472],{},"WakaTime\n",[20,7473,7474],{},[23,7475,7476],{},"Required in sections that use time tracking; needs your API key",[23,7478,7479],{},"See the slides below for MySQL and WakaTime setup",[11,7481,7483,7487],{"id":7482,"level":265},"step-4a-setup-mysql-extension",[16,7484,7486],{"id":7485},"step-4a-configure-mysql-extension","Step 4A: Configure MySQL Extension",[270,7488,7490,7545],{"gap":272,"left-width":274,"right-width":1591,"align":7489},"center",[277,7491,7492,7496],{"v-slot:left":279},[2565,7493,7495],{"id":7494},"connection-settings","Connection Settings",[20,7497,7498,7501,7542],{},[23,7499,7500],{},"Open the MySQL panel from the VS Code sidebar",[23,7502,7503,7504],{},"Create a new connection with your course database details",[20,7505,7506,7511,7517,7519,7521],{},[23,7507,2186,7508],{},[39,7509,7510],{},"db.ethereallab.app",[23,7512,7513,7514],{},"Port: ",[39,7515,7516],{},"3306",[23,7518,1257],{},[23,7520,2191],{},[23,7522,7523,7524],{},"Password: from your generated connection string\n",[20,7525,7526,7533],{},[23,7527,7528,7529],{},"Get it from the ",[146,7530,7532],{"href":2205,"rel":7531},[150],"course database page",[23,7534,7535,7536,1732,7539],{},"Use the 12 characters between ",[39,7537,7538],{},"ucid:",[39,7540,7541],{},"@",[23,7543,7544],{},"Save this connection; you will reuse it in later database lessons",[277,7546,7547],{"v-slot:right":279},[53,7548,7549],{},[283,7550],{"alt":7551,"src":7552,"variant":287},"MySQL extension connection setup for the course database","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fmysql-setup.png",[11,7554,7556,7560],{"id":7555,"level":265},"step-4b-setup-wakatime",[16,7557,7559],{"id":7558},"step-4b-configure-wakatime","Step 4B: Configure WakaTime",[270,7561,7562,7617],{"gap":272,"left-width":484,"right-width":485,"align":7489},[277,7563,7564,7568],{"v-slot:left":279},[2565,7565,7567],{"id":7566},"setup-order","Setup Order",[20,7569,7570,7577,7580,7583,7586,7589,7606,7611,7614],{},[23,7571,4412,7572],{},[146,7573,7576],{"href":7574,"rel":7575},"https:\u002F\u002Fwakatime.com\u002Fsignup",[150],"WakaTime",[23,7578,7579],{},"Create or open your account",[23,7581,7582],{},"Copy your API key from account settings",[23,7584,7585],{},"In VS Code, search Extensions for WakaTime",[23,7587,7588],{},"Install the WakaTime extension",[23,7590,7591,7592],{},"Open Command Palette:",[20,7593,7594,7600],{},[23,7595,7596,7597],{},"Windows\u002FLinux: ",[39,7598,7599],{},"Ctrl+Shift+P",[23,7601,7602,7603],{},"macOS: ",[39,7604,7605],{},"Cmd+Shift+P",[23,7607,1729,7608],{},[39,7609,7610],{},"WakaTime: API Key",[23,7612,7613],{},"Paste your API key",[23,7615,7616],{},"Restart VS Code if tracking does not appear right away",[277,7618,7619,7624,7631,7636,7643,7648],{"v-slot:right":279},[2491,7620,7621],{},[23,7622,7623],{},"WakaTime account settings:",[53,7625,7626],{},[283,7627],{"alt":7628,"src":7629,"variant":287,"max-height":7630},"WakaTime account settings API key detail","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fsettings-api-key-detail.png","14rem",[2491,7632,7633],{"start":2694},[23,7634,7635],{},"VS Code extension search:",[53,7637,7638],{},[283,7639],{"alt":7640,"src":7641,"variant":287,"max-height":7642},"VS Code Extensions search results showing WakaTime","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fvs-code-search.png","9rem",[2491,7644,7645],{"start":3262},[23,7646,7647],{},"VS Code API key command:",[53,7649,7650],{},[283,7651],{"alt":7652,"src":7653,"variant":287,"max-height":7642},"Command Palette with WakaTime API key command","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fvs-code-prompt.png",[11,7655,7657,7660],{"id":7656,"level":14},"step-5-optional-local-php",[16,7658,7659],{"id":7656},"Step 5: Optional Local PHP",[20,7661,7662,7665,7668,7676,7679],{},[23,7663,7664],{},"Useful for editor support",[23,7666,7667],{},"Useful for quick terminal checks",[23,7669,7670,7671],{},"Not the main course runtime\n",[20,7672,7673],{},[23,7674,7675],{},"Viable backup solution if VM lesson has issues",[23,7677,7678],{},"VM and Render still run the real app path",[23,7680,7681],{},"See the slides below for OS-specific install notes",[11,7683,7685,7688],{"id":7684,"level":265},"step-5a-windows-php-zip",[16,7686,7687],{"id":7684},"Step 5A: Windows PHP ZIP",[270,7689,7690,7721],{"gap":272,"left-width":1592,"right-width":1592},[277,7691,7692,7696],{"v-slot:left":279},[2565,7693,7695],{"id":7694},"download-and-extract","Download And Extract",[20,7697,7698,7701,7711,7716],{},[23,7699,7700],{},"Download PHP for Windows as a ZIP",[23,7702,7703,7704],{},"Extract it outside your repository",[20,7705,7706],{},[23,7707,3521,7708],{},[39,7709,7710],{},"C:\\tools\\php",[23,7712,7713,7714],{},"Add that extracted PHP folder to the user ",[39,7715,4205],{},[23,7717,7718,7719],{},"Restart Git Bash, PowerShell, and VS Code after editing ",[39,7720,4205],{},[277,7722,7723,7727,7743],{"v-slot:right":279},[2565,7724,7726],{"id":7725},"visual-checks","Visual Checks",[20,7728,7729,7735,7740],{},[23,7730,7731,7732],{},"The extracted folder contains ",[39,7733,7734],{},"php.exe",[23,7736,7737,7738],{},"The Path entry points to the folder, not to ",[39,7739,7734],{},[23,7741,7742],{},"A new terminal can run:",[1533,7744],{"language":1535,"src":7745,"label":7746},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fwindows-php-path-check-03.sh","windows-php-check.sh",[11,7748,7750,7753],{"id":7749,"level":265},"step-5b-macos-homebrew-php",[16,7751,7752],{"id":7749},"Step 5B: macOS Homebrew PHP",[270,7754,7755,7786],{"gap":272,"left-width":1592,"right-width":1592},[277,7756,7757,7761],{"v-slot:left":279},[2565,7758,7760],{"id":7759},"install-homebrew","Install Homebrew",[20,7762,7763,7766,7774,7777,7780,7783],{},[23,7764,7765],{},"Open Terminal",[23,7767,7768,7769],{},"Copy the install command from ",[146,7770,7773],{"href":7771,"rel":7772},"https:\u002F\u002Fbrew.sh\u002F",[150],"brew.sh",[23,7775,7776],{},"Expect Terminal to ask for your Mac password",[23,7778,7779],{},"Expect Homebrew to mention Command Line Tools if needed",[23,7781,7782],{},"At the end, Homebrew may print \"Next steps\"",[23,7784,7785],{},"Run those \"Next steps\" commands if shown",[277,7787,7788,7792,7796,7799],{"v-slot:right":279},[2565,7789,7791],{"id":7790},"then-install-php","Then Install PHP",[1533,7793],{"language":1535,"src":7794,"label":7795},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fmacos-install-php-homebrew-04.sh","macos-php.sh",[53,7797,7798],{},"Look for:",[20,7800,7801,7807,7812,7818],{},[23,7802,7803,7806],{},[39,7804,7805],{},"brew --version"," prints a version",[23,7808,7809,7811],{},[39,7810,7308],{}," prints PHP 8 output",[23,7813,7814,7815],{},"Apple Silicon Macs commonly use ",[39,7816,7817],{},"\u002Fopt\u002Fhomebrew",[23,7819,7820,7821],{},"Intel Macs commonly use ",[39,7822,7823],{},"\u002Fusr\u002Flocal",[11,7825,7827,7831,7833,7837],{"id":7826,"level":265},"step-5c-linux-php-cli",[16,7828,7830],{"id":7829},"step-5c-ubuntulinux-php-cli","Step 5C: Ubuntu\u002FLinux PHP CLI",[53,7832,2298],{},[1533,7834],{"language":1535,"src":7835,"label":7836},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Flinux-install-php-cli-05.sh","linux-php.sh",[20,7838,7839,7842,7845],{},[23,7840,7841],{},"This installs command-line PHP",[23,7843,7844],{},"This is only for local terminal checks",[23,7846,7847],{},"The later VM lesson installs Apache, PHP, and MySQL together",[11,7849,7851,7854,7856,7859,7861,7864],{"id":7850,"level":14},"step-6-verify-optional-php",[16,7852,7853],{"id":7850},"Step 6: Verify Optional PHP",[53,7855,2298],{},[1533,7857],{"language":1535,"src":7858},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fstep-6-verify-optional-p-01.sh",[53,7860,5469],{},[1533,7862],{"language":1542,"src":7863},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fexample-output-02.txt",[20,7865,7866,7869,7872],{},[23,7867,7868],{},"Exact version can differ",[23,7870,7871],{},"PHP 8 output means the terminal can find PHP",[23,7873,7874],{},"Windows may need a terminal or VS Code restart after PATH changes",[11,7876,7877,7879],{"id":4107,"level":14},[16,7878,4110],{"id":4107},[20,7880,7881,7884,7887,7890],{},[23,7882,7883],{},"Installing tools inside the repository folder",[23,7885,7886],{},"Opening the parent folder instead of the repo root",[23,7888,7889],{},"Editing a ZIP copy instead of the cloned repo",[23,7891,7892],{},"Installing extensions in the wrong VS Code profile",[11,7894,7895,7897],{"id":3197,"level":14},[16,7896,3200],{"id":3197},[20,7898,7899,7902,7905,7908,7911],{},[23,7900,7901],{},"VS Code opens your course repository root",[23,7903,7904],{},"Course profile is active",[23,7906,7907],{},"PHP Intelephense is installed",[23,7909,7910],{},"GitLens is installed",[23,7912,7913,7914,7916],{},"Optional: ",[39,7915,7308],{}," prints a PHP 8 version",[11,7918,7919,7921],{"id":2556,"level":14},[16,7920,2559],{"id":2556},[270,7922,7923,7941],{"gap":272,"left-width":1592,"right-width":1592},[277,7924,7925,7927],{"v-slot:left":279},[2565,7926,2568],{"id":2567},[20,7928,7929,7932,7935,7938],{},[23,7930,7931],{},"IDE: editor with development tools",[23,7933,7934],{},"Extension: add-on that changes VS Code behavior",[23,7936,7937],{},"Profile: saved VS Code setup",[23,7939,7940],{},"PATH: system setting used to find commands",[277,7942,7943,7945],{"v-slot:right":279},[2565,7944,2612],{"id":2611},[20,7946,7947,7954,7961],{},[23,7948,7949],{},[146,7950,7953],{"href":7951,"rel":7952},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fintrovideos\u002Fbasics",[150],"VS Code Getting Started",[23,7955,7956],{},[146,7957,7960],{"href":7958,"rel":7959},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fconfigure\u002Fprofiles",[150],"VS Code Profiles",[23,7962,7963],{},[146,7964,7967],{"href":7965,"rel":7966},"https:\u002F\u002Fwww.php.net\u002Fmanual\u002Fen\u002Finstall.php",[150],"PHP Installation",[11,7969,7970,7972],{"id":2664,"level":14},[16,7971,2667],{"id":2664},[20,7973,7974,7977,7980,7983,7994],{},[23,7975,7976],{},"VS Code installed as the course editor",[23,7978,7979],{},"Repository opens from its root folder",[23,7981,7982],{},"Course extensions live in a course profile",[23,7984,7985,7986],{},"Local PHP is optional for this Internet Applications path\n",[20,7987,7988,7991],{},[23,7989,7990],{},"Summer 2026 added information about VM setup in a future lesson to teach clearer Apache\u002FMySQL topics",[23,7992,7993],{},"VM, Apache, Render QA, and Render production remain the real runtime checks",[23,7995,7996],{},"Next: copy the instructor template into the repository",{"title":279,"searchDepth":2694,"depth":2694,"links":7998},[7999,8000,8001,8002,8003,8004,8005,8008,8009,8010,8011,8012,8013,8014,8015,8016,8017,8018],{"id":7259,"depth":2694,"text":7251},{"id":3351,"depth":2694,"text":3354},{"id":7291,"depth":2694,"text":7294},{"id":7312,"depth":2694,"text":7315},{"id":7337,"depth":2694,"text":7340},{"id":7375,"depth":2694,"text":7376},{"id":7404,"depth":2694,"text":7407,"children":8006},[8007],{"id":7410,"depth":3262,"text":7411},{"id":7485,"depth":2694,"text":7486},{"id":7558,"depth":2694,"text":7559},{"id":7656,"depth":2694,"text":7659},{"id":7684,"depth":2694,"text":7687},{"id":7749,"depth":2694,"text":7752},{"id":7829,"depth":2694,"text":7830},{"id":7850,"depth":2694,"text":7853},{"id":4107,"depth":2694,"text":4110},{"id":3197,"depth":2694,"text":3200},{"id":2556,"depth":2694,"text":2559},{"id":2664,"depth":2694,"text":2667},"Set up VS Code, course extensions, and optional local PHP checks.","First-pass timing estimate for VS Code installation, extension profile setup, optional PHP verification, and beginner folder checks.",{},"50","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment",{"title":7251,"description":8019},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment",[8027,8028,1909],"vscode","local-development","44:26","0s1N-m3LABc","https:\u002F\u002Fyoutu.be\u002F0s1N-m3LABc","Local Development Environment setup","X5U0DDKjg7X7HrYtDDcsE4QqlBLimZ9weKgnZlc8H2s",{"id":8035,"title":8036,"audience":6,"body":8037,"contentType":2762,"course":2763,"description":9082,"estimateBasis":9083,"estimatedDiscussionMinutes":6298,"estimatedLiveMinutes":4330,"estimatedTotalMinutes":9084,"extension":871,"meta":9085,"module":569,"navigation":2770,"order":9084,"path":9086,"promptAssist":2773,"seo":9087,"status":2775,"stem":9088,"tags":9089,"videoDuration":9090,"videoId":9091,"videoLink":9092,"videoTitle":9093,"week":569,"__hash__":9094},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository.md","Add Instructor Template To Your Repository",{"type":8,"value":8038,"toc":9054},[8039,8068,8110,8138,8171,8202,8245,8338,8382,8427,8472,8517,8589,8648,8721,8775,8849,8918,8950,9001,9025],[11,8040,8041,8043,8046],{"id":6320,"level":14},[16,8042,6323],{"id":6320},[53,8044,8045],{},"By the end, you should have:",[20,8047,8048,8051,8054,8060,8065],{},[23,8049,8050],{},"Cloned course repository open in the terminal",[23,8052,8053],{},"Starter template copied into the repository root",[23,8055,8056,8057],{},"Baseline commit on ",[39,8058,8059],{},"Module01-Course-Template",[23,8061,8062,8063],{},"Pull request merged into ",[39,8064,4519],{},[23,8066,8067],{},"Clean working tree before moving on",[11,8069,8071,8075],{"id":8070,"level":14},"step-1-open-clone",[16,8072,8074],{"id":8073},"step-1-open-the-cloned-repository","Step 1: Open The Cloned Repository",[270,8076,8077,8085],{"gap":272,"left-width":1592,"right-width":1592},[277,8078,8079,8081],{"v-slot:left":279},[53,8080,2298],{},[1533,8082],{"language":1535,"src":8083,"label":8084},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-1-open-the-cloned-repository-01.sh","open-cloned-repository.sh",[277,8086,8087,8089,8092],{"v-slot:right":279},[53,8088,5469],{},[1533,8090],{"language":4948,"src":8091,"label":5331},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fopen-cloned-repository-output.txt",[20,8093,8094,8099,8104],{},[23,8095,8096,8098],{},[39,8097,3438],{},": current working directory",[23,8100,8101,8103],{},[39,8102,6567],{},": current branch and file state",[23,8105,8106,8107,8109],{},"Important check: ",[39,8108,3438],{}," ends with your repository folder",[11,8111,8113,8117,8120,8123],{"id":8112,"level":14},"step-2-open-vscode",[16,8114,8116],{"id":8115},"step-2-open-the-repository-root","Step 2: Open The Repository Root",[53,8118,8119],{},"Run from inside the cloned repository folder:",[1533,8121],{"language":1535,"src":8122},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-2-open-the-reposito-01.sh",[20,8124,8125,8130,8135],{},[23,8126,8127,8129],{},[39,8128,39],{},": opens VS Code from the terminal",[23,8131,8132,8134],{},[39,8133,3503],{}," means \"this current folder\"",[23,8136,8137],{},"VS Code should show your repository folder, not the parent folder",[11,8139,8141,8145],{"id":8140,"level":14},"step-3-download-template",[16,8142,8144],{"id":8143},"step-3-download-the-instructor-template","Step 3: Download The Instructor Template",[20,8146,8147,8159,8162,8165,8168],{},[23,8148,8149,8150],{},"Open the instructor template repository",[20,8151,8152],{},[23,8153,8154],{},[146,8155,8158],{"href":8156,"rel":8157},"https:\u002F\u002Fgithub.com\u002FMattToegel\u002FIT202-2026",[150],"IT202-2026",[23,8160,8161],{},"Download the ZIP",[23,8163,8164],{},"Extract the ZIP",[23,8166,8167],{},"Copy scaffold contents into your repository root",[23,8169,8170],{},"See the slide below for the copy rule",[11,8172,8174,8178,8181,8184,8199],{"id":8173,"level":265},"template-copy-rule",[2565,8175,8177],{"id":8176},"copy-rule","Copy Rule",[53,8179,8180],{},"Copy the contents of the extracted template folder",[53,8182,8183],{},"Do not copy:",[20,8185,8186,8189,8196],{},[23,8187,8188],{},"The extracted wrapper folder as one extra nested folder",[23,8190,8191,8192,8195],{},"The template repository's hidden ",[39,8193,8194],{},".git"," folder",[23,8197,8198],{},"Old files from a different semester",[53,8200,8201],{},"Repository root should contain the starter folders directly",[11,8203,8205,8209,8212,8215],{"id":8204,"level":14},"step-4-check-structure",[16,8206,8208],{"id":8207},"step-4-check-the-starter-structure","Step 4: Check The Starter Structure",[53,8210,8211],{},"After copying, repository root should look similar to:",[1533,8213],{"language":1542,"src":8214},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-4-check-the-starter-02.txt",[20,8216,8217,8222,8231,8242],{},[23,8218,8219,8221],{},[39,8220,41],{}," should be directly inside your repository root",[23,8223,8224,8225,8228,8229],{},"Module folders and ",[39,8226,8227],{},"project"," live inside ",[39,8230,41],{},[23,8232,8233,2269,8235,2272,8237,8239,8240],{},[39,8234,1847],{},[39,8236,1852],{},[39,8238,1857],{}," stay outside ",[39,8241,41],{},[23,8243,8244],{},"See the slide below for the public\u002Fprivate folder boundary",[11,8246,8248,8252,8335],{"id":8247,"level":265},"public-html-boundary",[2565,8249,8251],{"id":8250},"public-and-private-boundary","Public And Private Boundary",[20,8253,8254,8288,8310,8315,8320,8326,8332],{},[23,8255,8256,8258,8259],{},[39,8257,41],{},": web root Apache can serve\n",[20,8260,8261,8271,8276,8282],{},[23,8262,8263,8266,8267,8270],{},[39,8264,8265],{},"m01"," through ",[39,8268,8269],{},"m10",": module practice folders",[23,8272,8273,8275],{},[39,8274,8227],{},": course project folder",[23,8277,8278,8281],{},[39,8279,8280],{},"index.php",": first browser entry point",[23,8283,8284,8287],{},[39,8285,8286],{},"test_db.php",": database connection check",[23,8289,8290,8292,8293],{},[39,8291,1847],{},": reusable PHP helpers\n",[20,8294,8295,8301],{},[23,8296,8297,8300],{},[39,8298,8299],{},".env.sample",": example local config file",[23,8302,8303,1732,8306,8309],{},[39,8304,8305],{},"config.php",[39,8307,8308],{},"db.php",": config and database helpers",[23,8311,8312,8314],{},[39,8313,1852],{},": shared page pieces",[23,8316,8317,8319],{},[39,8318,1857],{},": database setup scripts",[23,8321,8322,8325],{},[39,8323,8324],{},"Dockerfile",": consistent runtime setup",[23,8327,8328,8331],{},[39,8329,8330],{},"structure.md",": starter layout notes",[23,8333,8334],{},"Private folders should not be opened directly in the browser",[53,8336,8337],{},"Later server setup expects this folder boundary",[11,8339,8341,8345],{"id":8340,"level":14},"step-5-check-status",[16,8342,8344],{"id":8343},"step-5-create-the-template-branch","Step 5: Create The Template Branch",[270,8346,8347,8355],{"gap":272,"left-width":1592,"right-width":1592},[277,8348,8349,8351],{"v-slot:left":279},[53,8350,2298],{},[1533,8352],{"language":1535,"src":8353,"label":8354},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-5-create-template-branch-05.sh","create-template-branch.sh",[277,8356,8357,8360,8363],{"v-slot:right":279},[53,8358,8359],{},"Expected idea:",[1533,8361],{"language":1542,"src":8362,"label":5331},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstatus-after-template-copy.txt",[20,8364,8365,8371,8376,8379],{},[23,8366,8367,8370],{},[39,8368,8369],{},"git checkout -b",": create and move to a new branch",[23,8372,8373,8374],{},"Branch name: ",[39,8375,8059],{},[23,8377,8378],{},"New files listed as untracked",[23,8380,8381],{},"No changes means likely wrong folder or copy missed",[11,8383,8385,8389],{"id":8384,"level":14},"step-6-stage",[16,8386,8388],{"id":8387},"step-6-stage-the-baseline-files","Step 6: Stage The Baseline Files",[270,8390,8391,8399],{"gap":272,"left-width":1592,"right-width":1592},[277,8392,8393,8395],{"v-slot:left":279},[53,8394,2298],{},[1533,8396],{"language":1535,"src":8397,"label":8398},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-6-stage-the-baseline-files-06.sh","stage-baseline.sh",[277,8400,8401,8404,8422,8424],{"v-slot:right":279},[53,8402,8403],{},"What this means:",[20,8405,8406,8412,8417],{},[23,8407,8408,8411],{},[39,8409,8410],{},"git add",": choose files for the next commit",[23,8413,8414,8416],{},[39,8415,3503],{}," means current folder and contents",[23,8418,8419,8421],{},[39,8420,6567],{},": verify what is staged before committing",[53,8423,8359],{},[1533,8425],{"language":1542,"src":8426,"label":5331},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstatus-after-stage.txt",[11,8428,8430,8434],{"id":8429,"level":14},"step-7-commit",[16,8431,8433],{"id":8432},"step-7-commit-the-baseline","Step 7: Commit The Baseline",[270,8435,8436,8444],{"gap":272,"left-width":1592,"right-width":1592},[277,8437,8438,8440],{"v-slot:left":279},[53,8439,2298],{},[1533,8441],{"language":1535,"src":8442,"label":8443},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-7-commit-the-baseline-07.sh","commit-baseline.sh",[277,8445,8446,8448,8451],{"v-slot:right":279},[53,8447,8359],{},[1533,8449],{"language":1542,"src":8450,"label":5331},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fcommit-baseline-output.txt",[20,8452,8453,8459,8469],{},[23,8454,8455,8458],{},[39,8456,8457],{},"git commit",": save staged changes in local history",[23,8460,8461,8463,8464],{},[39,8462,6665],{},": commit message\n",[20,8465,8466],{},[23,8467,8468],{},"Message is required, even if empty",[23,8470,8471],{},"Baseline commit: starter state before custom work",[11,8473,8475,8479],{"id":8474,"level":14},"step-8-push",[16,8476,8478],{"id":8477},"step-8-push-the-template-branch","Step 8: Push The Template Branch",[270,8480,8481,8489],{"gap":272,"left-width":1592,"right-width":1592},[277,8482,8483,8485],{"v-slot:left":279},[53,8484,2298],{},[1533,8486],{"language":1535,"src":8487,"label":8488},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-8-push-to-github-08.sh","push-baseline.sh",[277,8490,8491,8493,8496],{"v-slot:right":279},[53,8492,8359],{},[1533,8494],{"language":1542,"src":8495,"label":5331},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fpush-baseline-output.txt",[20,8497,8498,8503,8509,8514],{},[23,8499,8500,8502],{},[39,8501,6728],{},": GitHub remote",[23,8504,8505,8508],{},[39,8506,8507],{},"-u",": remembers this branch's GitHub tracking branch",[23,8510,8511,8513],{},[39,8512,8059],{},": branch being sent",[23,8515,8516],{},"Refresh GitHub after the push",[11,8518,8520,8524],{"id":8519,"level":14},"step-9-open-pull-request",[16,8521,8523],{"id":8522},"step-9-open-the-pull-request","Step 9: Open The Pull Request",[270,8525,8526,8569],{"gap":272,"left-width":1592,"right-width":1592},[277,8527,8528,8530],{"v-slot:left":279},[53,8529,5386],{},[20,8531,8532,8535,8551,8556,8561,8564],{},[23,8533,8534],{},"Open your course repository",[23,8536,774,8537,8540],{},[2572,8538,8539],{},"Compare & pull request",[20,8541,8542],{},[23,8543,8544,8545,7352,8548],{},"Or use ",[2572,8546,8547],{},"Pull requests",[2572,8549,8550],{},"New pull request",[23,8552,8553,8554],{},"Set base branch to ",[39,8555,4519],{},[23,8557,8558,8559],{},"Set compare branch to ",[39,8560,8059],{},[23,8562,8563],{},"Confirm the changed files are the starter template files",[23,8565,774,8566],{},[2572,8567,8568],{},"Create pull request",[277,8570,8571,8574,8578],{"v-slot:right":279},[53,8572,8573],{},"Use a short title and description:",[1533,8575],{"language":1542,"src":8576,"label":8577},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fpull-request-description.txt","pull-request-description.txt",[20,8579,8580,8583,8586],{},[23,8581,8582],{},"Base receives the changes",[23,8584,8585],{},"Compare contains your branch work",[23,8587,8588],{},"If base and compare are reversed, do not create the pull request",[11,8590,8592,8598],{"id":8591,"level":14},"step-10-merge-sync-main",[16,8593,8595,8596],{"id":8594},"step-10-merge-and-sync-main","Step 10: Merge And Sync ",[39,8597,4519],{},[270,8599,8600,8622],{"gap":272,"left-width":1592,"right-width":1592},[277,8601,8602,8604,8616,8618],{"v-slot:left":279},[53,8603,5386],{},[20,8605,8606,8611],{},[23,8607,774,8608],{},[2572,8609,8610],{},"Merge pull request",[23,8612,774,8613],{},[2572,8614,8615],{},"Confirm merge",[53,8617,2224],{},[1533,8619],{"language":1535,"src":8620,"label":8621},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-10-sync-main-after-pr-10.sh","sync-main-after-pr.sh",[277,8623,8624,8626,8629],{"v-slot:right":279},[53,8625,8359],{},[1533,8627],{"language":1542,"src":8628,"label":5331},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fsync-main-after-pr-output.txt",[20,8630,8631,8637,8643],{},[23,8632,8633,8636],{},[39,8634,8635],{},"git checkout main",": return to the main branch",[23,8638,8639,8642],{},[39,8640,8641],{},"git pull origin main",": download the merged template files",[23,8644,8645,8646,7045],{},"Continue only when local ",[39,8647,4519],{},[11,8649,8651,8657],{"id":8650,"level":14},"step-11-create-local-env",[16,8652,8653,8654],{"id":8650},"Step 11: Create Local ",[39,8655,8656],{},".env",[270,8658,8659,8681],{"gap":272,"left-width":1592,"right-width":1592},[277,8660,8661,8664,8668],{"v-slot:left":279},[53,8662,8663],{},"Run from the repository root:",[1533,8665],{"language":1535,"src":8666,"label":8667},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-11-create-local-env-11.sh","create-local-env.sh",[20,8669,8670],{},[23,8671,8672,8673,8676,8677],{},"Get ",[39,8674,8675],{},"DB_URL"," from ",[146,8678,8680],{"href":2205,"rel":8679},[150],"courses.ethereallab.app\u002Fdatabase",[277,8682,8683,8686,8691],{"v-slot:right":279},[53,8684,8685],{},"Fill in values similar to:",[1533,8687],{"language":8688,"src":8689,"label":8690},"dotenv","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Flocal-env-example.txt","lib\u002F.env",[20,8692,8693,8698,8703,8706,8711,8716],{},[23,8694,8695,8697],{},[39,8696,8656],{}," stores local secrets",[23,8699,652,8700,8702],{},[39,8701,8656],{}," on your computer only",[23,8704,8705],{},"Do not commit your real connection string",[23,8707,8708,8709],{},"Paste the generated database connection string as ",[39,8710,8675],{},[23,8712,8713,8715],{},[39,8714,8305],{}," loads local or hosted environment variables",[23,8717,8718,8719],{},"Do not paste secrets directly into ",[39,8720,8305],{},[11,8722,8724,8728],{"id":8723,"level":14},"step-12-test-local-db",[16,8725,8727],{"id":8726},"step-12-test-local-database-connection","Step 12: Test Local Database Connection",[270,8729,8730,8738],{"gap":272,"left-width":1592,"right-width":1592},[277,8731,8732,8734],{"v-slot:left":279},[53,8733,8663],{},[1533,8735],{"language":1535,"src":8736,"label":8737},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-12-test-local-db-12.sh","run-local-php.sh",[277,8739,8740,8743,8747],{"v-slot:right":279},[53,8741,8742],{},"Then open:",[1533,8744],{"language":1542,"src":8745,"label":8746},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Ftest-db-url.txt","browser-url.txt",[20,8748,8749,8755,8761,8769],{},[23,8750,8751,8754],{},[39,8752,8753],{},"php -S",": starts PHP's built-in local server",[23,8756,8757,8760],{},[39,8758,8759],{},"-t public_html",": serves the course web root",[23,8762,8763,8765,8766,8768],{},[39,8764,8286],{},": confirms PHP can read ",[39,8767,8656],{}," and connect to MySQL",[23,8770,8771,8772,8774],{},"Stop the server with ",[39,8773,4162],{}," when finished",[11,8776,8778,8786,8791],{"id":8777,"level":14},"step-13-enable-pdo-mysql",[16,8779,8781,8782,8785],{"id":8780},"step-13-enable-pdo_mysql-if-needed","Step 13: Enable ",[39,8783,8784],{},"pdo_mysql"," If Needed",[53,8787,8788,8789,3503],{},"This is usually a Windows PHP ZIP setup issue. macOS and Linux usually install MySQL support through Homebrew or ",[39,8790,1355],{},[270,8792,8793,8824],{"gap":272,"left-width":1592,"right-width":1592},[277,8794,8795,8798,8802,8805],{"v-slot:left":279},[53,8796,8797],{},"Find the PHP folder:",[1533,8799],{"language":1535,"src":8800,"label":8801},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-13-find-php-folder-13.sh","find-php-folder.sh",[53,8803,8804],{},"In that folder:",[20,8806,8807,8813,8819],{},[23,8808,8809,8810],{},"Find ",[39,8811,8812],{},"php.ini-development",[23,8814,8815,8816],{},"Copy it as ",[39,8817,8818],{},"php.ini",[23,8820,5769,8821,8823],{},[39,8822,8818],{}," in your editor",[277,8825,8826,8829,8832,8835,8839],{"v-slot:right":279},[53,8827,8828],{},"Uncomment these lines:",[1533,8830],{"language":2081,"src":8831,"label":8818},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fphp-ini-pdo-mysql-settings.txt",[53,8833,8834],{},"Mac\u002FLinux usually use:",[1533,8836],{"language":1535,"src":8837,"label":8838},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fmacos-linux-pdo-mysql-commands-14.sh","macos-linux-php-mysql.sh",[20,8840,8841,8846],{},[23,8842,8843,8844],{},"Restart the php dev server after changing ",[39,8845,8818],{},[23,8847,8848],{},"Run Step 12 again after enabling the extension",[11,8850,8852,8854,8857],{"id":8851,"level":14},"quick-check-final",[16,8853,3200],{"id":3197},[53,8855,8856],{},"Confirm all of these:",[20,8858,8859,8862,8870,8873,8878,8887,8893,8898,8903,8909],{},[23,8860,8861],{},"GitHub shows the starter files",[23,8863,8864,8865,8867,8868],{},"GitHub shows a pull request from ",[39,8866,8059],{}," into ",[39,8869,4519],{},[23,8871,8872],{},"The pull request is merged",[23,8874,6792,8875,8877],{},[39,8876,4519],{}," says the working tree is clean",[23,8879,8880,8266,8883,8886],{},[39,8881,8882],{},"public_html\u002Fm01",[39,8884,8885],{},"public_html\u002Fm10"," exist",[23,8888,8889,8892],{},[39,8890,8891],{},"public_html\u002Fproject"," exists",[23,8894,8895,8897],{},[39,8896,41],{}," is not nested inside another accidental folder",[23,8899,8900,8902],{},[39,8901,8690],{}," exists locally and is not committed with real secrets",[23,8904,8905,8908],{},[39,8906,8907],{},"http:\u002F\u002Flocalhost:3000\u002Ftest_db.php"," confirms the database connection",[23,8910,8911,8912,8914,8915,8917],{},"Windows PHP has ",[39,8913,8784],{}," enabled if ",[39,8916,8286],{}," reports a missing driver",[11,8919,8921,8925,8927,8930,8939],{"id":8920,"level":14},"reset-check",[16,8922,8924],{"id":8923},"if-something-looks-wrong","If Something Looks Wrong",[53,8926,2298],{},[1533,8928],{"language":1535,"src":8929},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fif-something-looks-wrong-03.sh",[8931,8932,8933],"blockquote",{},[53,8934,8935,8936,8938],{},"Tip: ",[39,8937,5921],{}," prints the repository root when your current folder is inside a Git repository",[20,8940,8941,8944,8947],{},[23,8942,8943],{},"Output should point to your course repository",[23,8945,8946],{},"If it points somewhere else, move folders before continuing",[23,8948,8949],{},"Avoid cloning inside another cloned repository",[11,8951,8952,8954],{"id":4107,"level":14},[16,8953,4110],{"id":4107},[20,8955,8956,8959,8962,8967,8970,8973,8978,8987,8992,8995],{},[23,8957,8958],{},"Opening the parent folder instead of the repository root",[23,8960,8961],{},"Copying the instructor template folder as a nested folder",[23,8963,8964,8965,8195],{},"Copying the template ",[39,8966,8194],{},[23,8968,8969],{},"Keeping the downloaded ZIP inside the repository",[23,8971,8972],{},"Re-cloning the repository instead of opening the existing clone",[23,8974,8975,8976],{},"Putting module folders outside ",[39,8977,41],{},[23,8979,8980,8981,2370,8983,8986],{},"Renaming ",[39,8982,8265],{},[39,8984,8985],{},"M1"," or mixing folder casing",[23,8988,8989,8990],{},"Doing template work directly on ",[39,8991,4519],{},[23,8993,8994],{},"Reversing base and compare branches in the pull request",[23,8996,8997,8998,9000],{},"Forgetting to sync local ",[39,8999,4519],{}," after the pull request is merged",[11,9002,9003,9005],{"id":2567,"level":14},[16,9004,2568],{"id":2567},[20,9006,9007,9010,9013,9016,9019,9022],{},[23,9008,9009],{},"Repository root: top folder of the cloned project",[23,9011,9012],{},"Baseline: starter state before custom work begins",[23,9014,9015],{},"Pull request: GitHub review page used to merge branch work",[23,9017,9018],{},"Web root: folder served to the browser",[23,9020,9021],{},"Scaffold: starter folders that organize future work",[23,9023,9024],{},"Staging: choosing files for the next commit",[11,9026,9027,9029,9032],{"id":2664,"level":14},[16,9028,2667],{"id":2664},[53,9030,9031],{},"Before leaving this presentation, confirm the following:",[20,9033,9034,9037,9040,9043,9049],{},[23,9035,9036],{},"You still have one clone for your repository",[23,9038,9039],{},"Your VS Code is able to open directly to your repository",[23,9041,9042],{},"Your repository has the full starter baseline correctly structured",[23,9044,9045,9046,9048],{},"GitHub remote ",[39,9047,4519],{}," has the baseline content",[23,9050,6792,9051,9053],{},[39,9052,4519],{}," was synchronized",{"title":279,"searchDepth":2694,"depth":2694,"links":9055},[9056,9057,9058,9059,9062,9065,9066,9067,9068,9069,9070,9072,9074,9075,9077,9078,9079,9080,9081],{"id":6320,"depth":2694,"text":6323},{"id":8073,"depth":2694,"text":8074},{"id":8115,"depth":2694,"text":8116},{"id":8143,"depth":2694,"text":8144,"children":9060},[9061],{"id":8176,"depth":3262,"text":8177},{"id":8207,"depth":2694,"text":8208,"children":9063},[9064],{"id":8250,"depth":3262,"text":8251},{"id":8343,"depth":2694,"text":8344},{"id":8387,"depth":2694,"text":8388},{"id":8432,"depth":2694,"text":8433},{"id":8477,"depth":2694,"text":8478},{"id":8522,"depth":2694,"text":8523},{"id":8594,"depth":2694,"text":9071},"Step 10: Merge And Sync main",{"id":8650,"depth":2694,"text":9073},"Step 11: Create Local .env",{"id":8726,"depth":2694,"text":8727},{"id":8780,"depth":2694,"text":9076},"Step 13: Enable pdo_mysql If Needed",{"id":3197,"depth":2694,"text":3200},{"id":8923,"depth":2694,"text":8924},{"id":4107,"depth":2694,"text":4110},{"id":2567,"depth":2694,"text":2568},{"id":2664,"depth":2694,"text":2667},"Continue from your cloned course repository, copy in the instructor template, and merge the baseline files through a pull request.","Face-to-face class of about 40 students; starts from an existing clone and includes template copy checks, ZIP extraction, first commit verification, and common folder mistakes.","60",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository",{"title":8036,"description":9082},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository",[6307,277,4554],"47:11","4n0-QuXO_Aw","https:\u002F\u002Fyoutu.be\u002F4n0-QuXO_Aw","Adding Instructor\u002FCourse Template","iYq9WdND1ODBRrXLU2gX9dNCXvDc-Kvqufsokl_jg3E",{"id":9096,"title":9097,"audience":6,"body":9098,"contentType":2762,"course":2763,"description":9807,"estimateBasis":9808,"estimatedDiscussionMinutes":6298,"estimatedLiveMinutes":7237,"estimatedTotalMinutes":4331,"extension":871,"meta":9809,"module":569,"navigation":2770,"order":6299,"path":9810,"promptAssist":2773,"seo":9811,"status":2775,"stem":9812,"tags":9813,"videoDuration":9815,"videoId":9816,"videoLink":9817,"videoTitle":9818,"week":569,"__hash__":9819},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches.md","QA And Prod Branches",{"type":8,"value":9099,"toc":9786},[9100,9134,9182,9204,9258,9323,9381,9431,9496,9537,9628,9668,9695,9753],[11,9101,9102,9104,9106],{"id":6320,"level":14},[16,9103,6323],{"id":6320},[53,9105,6326],{},[20,9107,9108,9117,9122,9126,9131],{},[23,9109,9110,9111,1732,9114],{},"Understand the purpose and usage of ",[39,9112,9113],{},"qa",[39,9115,9116],{},"prod",[23,9118,9119,9120],{},"Create and push ",[39,9121,9113],{},[23,9123,9119,9124],{},[39,9125,9116],{},[23,9127,9128,9129],{},"Keep local work pointed at ",[39,9130,9113],{},[23,9132,9133],{},"Confirm GitHub has the expected branches",[11,9135,9137,9140,9175],{"id":9136,"level":14},"branch-roles",[16,9138,9139],{"id":9136},"Branch Roles",[20,9141,9142,9152,9162,9172],{},[23,9143,9144,9146,9147],{},[39,9145,4519],{},": starter baseline and shared source branch\n",[20,9148,9149],{},[23,9150,9151],{},"Most projects stick with this; we'll split ours into development lanes",[23,9153,9154,9156,9157],{},[39,9155,9113],{},": public testing and evidence branch\n",[20,9158,9159],{},[23,9160,9161],{},"Normal branch to return to before new course work",[23,9163,9164,9166,9167],{},[39,9165,9116],{},": stable grading and evaluation branch\n",[20,9168,9169],{},[23,9170,9171],{},"Protected from everyday local edits",[23,9173,9174],{},"Later deployment setup connects Render to these branches",[53,9176,9177,9178,7352,9180],{},"Course flow: feature or homework branch -> ",[39,9179,9113],{},[39,9181,9116],{},[11,9183,9184,9186,9189,9193],{"id":132,"level":14},[16,9185,135],{"id":132},[53,9187,9188],{},"Run inside the course repository:",[1533,9190],{"label":9191,"language":1535,"src":9192},"before-you-start.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fbefore-you-start.sh",[20,9194,9195,9198,9201],{},[23,9196,9197],{},"Working tree should be clean",[23,9199,9200],{},"Starter baseline already pushed to GitHub",[23,9202,9203],{},"Stop if Git says files are modified or untracked",[11,9205,9207,9213],{"id":9206,"level":14},"step-1-sync-main",[16,9208,9210,9211],{"id":9209},"step-1-start-from-main","Step 1: Start From ",[39,9212,4519],{},[270,9214,9215,9223],{"gap":272,"left-width":1592,"right-width":1592},[277,9216,9217,9219],{"v-slot:left":279},[53,9218,2298],{},[1533,9220],{"label":9221,"language":1535,"src":9222},"sync-main.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fsync-main.sh",[277,9224,9225,9227,9230],{"v-slot:right":279},[53,9226,5469],{},[1533,9228],{"label":5331,"language":1542,"src":9229},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fsync-main-output.txt",[20,9231,9232,9239],{},[23,9233,9234,9236,9237],{},[39,9235,8635],{},": switch to ",[39,9238,4519],{},[23,9240,9241,9243,9244,9246,9247],{},[39,9242,8641],{},": get the latest ",[39,9245,4519],{}," from GitHub\n",[20,9248,9249,9253],{},[23,9250,9251,8502],{},[39,9252,6728],{},[23,9254,9255,9257],{},[39,9256,4519],{},": remote branch being pulled",[11,9259,9261,9267],{"id":9260,"level":14},"step-2-create-qa",[16,9262,9264,9265],{"id":9263},"step-2-create-and-push-qa","Step 2: Create And Push ",[39,9266,9113],{},[270,9268,9269,9277],{"gap":272,"left-width":1592,"right-width":1592},[277,9270,9271,9273],{"v-slot:left":279},[53,9272,2298],{},[1533,9274],{"label":9275,"language":1535,"src":9276},"create-qa.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-qa.sh",[277,9278,9279,9281,9284],{"v-slot:right":279},[53,9280,5469],{},[1533,9282],{"label":5331,"language":1542,"src":9283},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-qa-output.txt",[20,9285,9286,9303],{},[23,9287,9288,9291,9292,9294,9295],{},[39,9289,9290],{},"git checkout -b qa",": create ",[39,9293,9113],{}," and switch to it\n",[20,9296,9297],{},[23,9298,9299,9302],{},[39,9300,9301],{},"-b",": creates a new branch of the following name",[23,9304,9305,9308,9309,9311,9312],{},[39,9306,9307],{},"git push -u origin qa",": send ",[39,9310,9113],{}," to GitHub\n",[20,9313,9314],{},[23,9315,9316,9318,9319,9322],{},[39,9317,8507],{},": remember ",[39,9320,9321],{},"origin\u002Fqa"," as the upstream branch",[11,9324,9326,9332],{"id":9325,"level":14},"step-3-create-prod",[16,9327,9329,9330],{"id":9328},"step-3-create-and-push-prod","Step 3: Create And Push ",[39,9331,9116],{},[270,9333,9334,9342],{"gap":272,"left-width":1592,"right-width":1592},[277,9335,9336,9338],{"v-slot:left":279},[53,9337,2298],{},[1533,9339],{"label":9340,"language":1535,"src":9341},"create-prod.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-prod.sh",[277,9343,9344,9346,9349],{"v-slot:right":279},[53,9345,5469],{},[1533,9347],{"label":5331,"language":1542,"src":9348},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-prod-output.txt",[20,9350,9351,9359,9364,9376],{},[23,9352,7387,9353,9355,9356,9358],{},[39,9354,9116],{}," from the current ",[39,9357,9113],{}," branch",[23,9360,9361],{},[39,9362,9363],{},"git checkout -b prod",[23,9365,9366,9367,9311,9369],{},"Push ",[39,9368,9116],{},[20,9370,9371],{},[23,9372,9373],{},[39,9374,9375],{},"git push origin prod",[23,9377,9378,9380],{},[39,9379,9116],{}," starts from the same clean baseline",[11,9382,9384,9389],{"id":9383,"level":14},"step-4-return-to-qa",[16,9385,9386,9387],{"id":9383},"Step 4: Return To ",[39,9388,9113],{},[270,9390,9391,9399],{"gap":272,"left-width":1592,"right-width":1592},[277,9392,9393,9395],{"v-slot:left":279},[53,9394,2298],{},[1533,9396],{"label":9397,"language":1535,"src":9398},"return-to-qa.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Freturn-to-qa.sh",[277,9400,9401,9403,9406],{"v-slot:right":279},[53,9402,5469],{},[1533,9404],{"label":5331,"language":1542,"src":9405},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Freturn-to-qa-output.txt",[20,9407,9408,9413,9418],{},[23,9409,9410,9412],{},[39,9411,9113],{}," should have the asterisk",[23,9414,9415,9417],{},[39,9416,9116],{}," should still exist on GitHub",[23,9419,9420,9421,9423],{},"Do not start normal course work from ",[39,9422,9116],{},[20,9424,9425],{},[23,9426,9427,9428,9430],{},"We'll remove local ",[39,9429,9116],{}," to avoid this issue",[11,9432,9434,9440],{"id":9433,"level":14},"step-5-delete-local-prod",[16,9435,9437,9438],{"id":9436},"step-5-remove-local-prod","Step 5: Remove Local ",[39,9439,9116],{},[270,9441,9442,9450],{"gap":272,"left-width":1592,"right-width":1592},[277,9443,9444,9446],{"v-slot:left":279},[53,9445,2298],{},[1533,9447],{"label":9448,"language":1535,"src":9449},"delete-local-prod.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fdelete-local-prod.sh",[277,9451,9452,9454,9457],{"v-slot:right":279},[53,9453,5469],{},[1533,9455],{"label":5331,"language":1542,"src":9456},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fdelete-local-prod-output.txt",[20,9458,9459,9481],{},[23,9460,9461,9464,9465,9467],{},[39,9462,9463],{},"git branch -d prod",": delete local ",[39,9466,9116],{},[20,9468,9469,9475],{},[23,9470,9471,9474],{},[39,9472,9473],{},"-d",": delete only if Git considers it safe",[23,9476,9477,9480],{},[39,9478,9479],{},"-D",": can be used as a forced delete",[23,9482,9483,9486,9487],{},[39,9484,9485],{},"git branch -r",": list remote branches\n",[20,9488,9489],{},[23,9490,9491,9492,9495],{},"Confirms ",[39,9493,9494],{},"origin\u002Fprod"," still exists",[11,9497,9499,9502,9505,9508,9522,9525],{"id":9498,"level":14},"github-check",[16,9500,9501],{"id":9498},"GitHub Check",[53,9503,9504],{},"Open the branch dropdown on GitHub",[53,9506,9507],{},"You should see:",[20,9509,9510,9514,9518],{},[23,9511,9512],{},[39,9513,4519],{},[23,9515,9516],{},[39,9517,9113],{},[23,9519,9520],{},[39,9521,9116],{},[53,9523,9524],{},"Branch roles:",[20,9526,9527,9532],{},[23,9528,9529,9531],{},[39,9530,9113],{},": testing and evidence",[23,9533,9534,9536],{},[39,9535,9116],{},": stable grading target",[11,9538,9540,9544],{"id":9539,"level":14},"normal-workflow",[16,9541,9543],{"id":9542},"normal-workflow-after-setup","Normal Workflow After Setup",[2491,9545,9546,9563,9571,9581,9586,9600,9603,9610,9622],{},[23,9547,9548,9549,9551],{},"Return to ",[39,9550,9113],{},[20,9552,9553,9558],{},[23,9554,9555],{},[39,9556,9557],{},"git checkout qa",[23,9559,9560],{},[39,9561,9562],{},"git pull origin qa",[23,9564,9565,9566],{},"Create a feature or homework branch\n",[20,9567,9568],{},[23,9569,9570],{},"Branch name matches the task",[23,9572,9573,9574],{},"Commit the work on that branch\n",[20,9575,9576],{},[23,9577,1316,9578,9580],{},[39,9579,6567],{}," before each Git command",[23,9582,9583,9584],{},"Push the branch and open a pull request into ",[39,9585,9113],{},[23,9587,9588,9589,9591,9592],{},"Merge into ",[39,9590,9113],{}," after review\n",[20,9593,9594],{},[23,9595,9596,9597,9599],{},"QA deployment will update from ",[39,9598,9113],{}," after Render setup",[23,9601,9602],{},"Test the QA version",[23,9604,9605,9606,8867,9608],{},"Open a pull request from ",[39,9607,9113],{},[39,9609,9116],{},[23,9611,9588,9612,9614,9615],{},[39,9613,9116],{}," when stable\n",[20,9616,9617],{},[23,9618,9619,9620,9599],{},"Production deployment will use ",[39,9621,9116],{},[23,9623,9624,9625,9627],{},"Return locally to ",[39,9626,9113],{}," and pull before the next task",[11,9629,9630,9632],{"id":4107,"level":14},[16,9631,4110],{"id":4107},[20,9633,9634,9639,9644,9652,9660,9663],{},[23,9635,9636,9637],{},"Working directly on ",[39,9638,9116],{},[23,9640,9641,9642],{},"Forgetting to return to ",[39,9643,9113],{},[23,9645,9646,9647,9649,9650],{},"Pushing ",[39,9648,9113],{}," but not ",[39,9651,9116],{},[23,9653,9654,9655,9657,9658],{},"Deleting remote ",[39,9656,9116],{}," instead of local ",[39,9659,9116],{},[23,9661,9662],{},"Assuming GitHub has the branch without checking",[23,9664,9665,9666,7045],{},"Starting new work before ",[39,9667,6567],{},[11,9669,9670,9672,9675],{"id":3197,"level":14},[16,9671,3200],{"id":3197},[53,9673,9674],{},"Answer before moving on:",[20,9676,9677,9680,9683,9686,9692],{},[23,9678,9679],{},"Which branch should QA deployment watch?",[23,9681,9682],{},"Which branch should production grading use?",[23,9684,9685],{},"Which branch should you return to before new work?",[23,9687,9688,9689,9691],{},"Why remove local ",[39,9690,9116],{}," after pushing it?",[23,9693,9694],{},"What future setup connects Render to these branches?",[11,9696,9697,9699],{"id":2611,"level":14},[16,9698,2559],{"id":2556},[270,9700,9701,9726],{"gap":272,"left-width":1592,"right-width":1592},[277,9702,9703,9705],{"v-slot:left":279},[2565,9704,2568],{"id":2567},[20,9706,9707,9710,9713,9718,9723],{},[23,9708,9709],{},"Branch: named line of Git history",[23,9711,9712],{},"Upstream: remote branch Git remembers for push\u002Fpull",[23,9714,9715,9717],{},[39,9716,9113],{},": public testing branch",[23,9719,9720,9722],{},[39,9721,9116],{},": stable grading branch",[23,9724,9725],{},"Remote-only branch: exists on GitHub, not locally",[277,9727,9728,9730],{"v-slot:right":279},[2565,9729,2612],{"id":2611},[20,9731,9732,9739,9746],{},[23,9733,7140,9734],{},[146,9735,9738],{"href":9736,"rel":9737},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fget-started\u002Fusing-git\u002Fabout-git#about-branches",[150],"About branches",[23,9740,7140,9741],{},[146,9742,9745],{"href":9743,"rel":9744},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpull-requests\u002Fcollaborating-with-pull-requests\u002Fproposing-changes-to-your-work-with-pull-requests\u002Fabout-pull-requests",[150],"About pull requests",[23,9747,7125,9748],{},[146,9749,9752],{"href":9750,"rel":9751},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Branching-Branches-in-a-Nutshell",[150],"Git Branching",[11,9754,9755,9757,9759],{"id":2664,"level":14},[16,9756,2667],{"id":2664},[53,9758,2670],{},[20,9760,9761,9770,9774,9778,9783],{},[23,9762,9763,9764,2269,9766,2272,9768],{},"Explain ",[39,9765,4519],{},[39,9767,9113],{},[39,9769,9116],{},[23,9771,9119,9772],{},[39,9773,9113],{},[23,9775,9119,9776],{},[39,9777,9116],{},[23,9779,9780,9781],{},"Keep local work branched from ",[39,9782,9113],{},[23,9784,9785],{},"Verify remote branches on GitHub",{"title":279,"searchDepth":2694,"depth":2694,"links":9787},[9788,9789,9790,9791,9793,9795,9797,9799,9801,9802,9803,9804,9805,9806],{"id":6320,"depth":2694,"text":6323},{"id":9136,"depth":2694,"text":9139},{"id":132,"depth":2694,"text":135},{"id":9209,"depth":2694,"text":9792},"Step 1: Start From main",{"id":9263,"depth":2694,"text":9794},"Step 2: Create And Push qa",{"id":9328,"depth":2694,"text":9796},"Step 3: Create And Push prod",{"id":9383,"depth":2694,"text":9798},"Step 4: Return To qa",{"id":9436,"depth":2694,"text":9800},"Step 5: Remove Local prod",{"id":9498,"depth":2694,"text":9501},{"id":9542,"depth":2694,"text":9543},{"id":4107,"depth":2694,"text":4110},{"id":3197,"depth":2694,"text":3200},{"id":2556,"depth":2694,"text":2559},{"id":2664,"depth":2694,"text":2667},"Create the Internet Applications QA and production branches, then connect each branch to its role in the course workflow.","Face-to-face class of about 40 students; includes branch roles, command practice, GitHub branch checks, and QA\u002Fprod workflow questions.",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches",{"title":9097,"description":9807},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches",[4554,7242,9113,9814],"production","10:35","32XilHQwRiY","https:\u002F\u002Fyoutu.be\u002F32XilHQwRiY","Create QA and Prod Branches","GZx1sXtI0BMbyb6Gbpj7aoBvczhhR-FV7YpFE4j4UCs",{"id":9821,"title":9822,"audience":6,"body":9823,"contentType":2762,"course":2763,"description":10630,"estimateBasis":10631,"estimatedDiscussionMinutes":6298,"estimatedLiveMinutes":4331,"estimatedTotalMinutes":6299,"extension":871,"meta":10632,"module":569,"navigation":2770,"order":1446,"path":10633,"promptAssist":2773,"seo":10634,"status":2775,"stem":10635,"tags":10636,"videoDuration":10639,"videoId":10640,"videoLink":10641,"videoTitle":10642,"week":569,"__hash__":10643},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup.md","Render Setup",{"type":8,"value":9824,"toc":10609},[9825,9852,9875,9904,9972,10033,10068,10104,10141,10191,10237,10272,10318,10355,10383,10415,10462,10495,10563],[11,9826,9828,9831],{"id":9827,"level":14},"render-setup-title",[16,9829,9822],{"id":9830},"render-setup",[20,9832,9833,9836,9841,9846,9849],{},[23,9834,9835],{},"Connect GitHub repo to Render",[23,9837,9838,9839],{},"Create a QA service from ",[39,9840,9113],{},[23,9842,9843,9844],{},"Create a production service from ",[39,9845,9116],{},[23,9847,9848],{},"Add the course database connection string",[23,9850,9851],{},"Verify live URLs and deploy logs",[11,9853,9854,9856,9858],{"id":5229,"level":14},[16,9855,5232],{"id":5229},[53,9857,6326],{},[20,9859,9860,9863,9866,9869,9872],{},[23,9861,9862],{},"Explain what Render does in the course workflow",[23,9864,9865],{},"Create separate QA and production services",[23,9867,9868],{},"Connect each service to the correct branch",[23,9870,9871],{},"Read Render logs when a deploy fails",[23,9873,9874],{},"Identify which deployed URL to submit or test",[11,9876,9878,9881,9898],{"id":9877,"level":14},"what-render-does",[16,9879,9880],{"id":9877},"What Render Does",[20,9882,9883,9886,9889,9892,9895],{},[23,9884,9885],{},"Hosts your PHP app from GitHub",[23,9887,9888],{},"Watches a selected branch",[23,9890,9891],{},"Rebuilds when that branch changes",[23,9893,9894],{},"Stores secrets as environment variables",[23,9896,9897],{},"Gives each service a public URL",[53,9899,9900,9901],{},"Course loop: ",[39,9902,9903],{},"local work -> GitHub branch -> Render URL",[11,9905,9907,9909],{"id":9906,"level":14},"free-tier-and-before-start",[16,9908,135],{"id":132},[270,9910,9911,9940],{"gap":272,"left-width":1592,"right-width":1592},[277,9912,9913,9917],{"v-slot:left":279},[2565,9914,9916],{"id":9915},"free-tier","Free Tier",[20,9918,9919,9929,9937],{},[23,9920,889,9921,9924],{},[39,9922,9923],{},"Free",[20,9925,9926],{},[23,9927,9928],{},"Render may default to a paid plan",[23,9930,9931,9932],{},"Free services can sleep",[20,9933,9934],{},[23,9935,9936],{},"First visit after sleep may be slow",[23,9938,9939],{},"Avoid extra services unless instructed",[277,9941,9942,9946],{"v-slot:right":279},[2565,9943,9945],{"id":9944},"repo-ready","Repo Ready",[20,9947,9948,9951,9956,9965],{},[23,9949,9950],{},"Starter files committed and pushed",[23,9952,9953,9955],{},[39,9954,8324],{}," in repo root",[23,9957,9958,2269,9960,2272,9962,9964],{},[39,9959,41],{},[39,9961,1847],{},[39,9963,1852],{}," present",[23,9966,9967,1732,9969,9971],{},[39,9968,9113],{},[39,9970,9116],{}," branches exist on GitHub",[11,9973,9975,9978],{"id":9974,"level":14},"target-architecture",[16,9976,9977],{"id":9974},"Target Architecture",[270,9979,9980,10008],{"gap":272,"left-width":1592,"right-width":1592},[277,9981,9982,9986],{"v-slot:left":279},[2565,9983,9985],{"id":9984},"qa-service","QA Service",[20,9987,9988,9994,9999,10002],{},[23,9989,9990,9991],{},"Name: ",[39,9992,9993],{},"\u003Cucid>-it202-\u003Csection>-qa",[23,9995,9996,9997],{},"Watches ",[39,9998,9113],{},[23,10000,10001],{},"Used for testing and evidence",[23,10003,10004,10005],{},"URL ends with ",[39,10006,10007],{},"-qa.onrender.com",[277,10009,10010,10014],{"v-slot:right":279},[2565,10011,10013],{"id":10012},"production-service","Production Service",[20,10015,10016,10021,10025,10028],{},[23,10017,9990,10018],{},[39,10019,10020],{},"\u003Cucid>-it202-\u003Csection>-prod",[23,10022,9996,10023],{},[39,10024,9116],{},[23,10026,10027],{},"Stable version after QA checks",[23,10029,10004,10030],{},[39,10031,10032],{},"-prod.onrender.com",[11,10034,10036,10040],{"id":10035,"level":14},"step-1-sign-up",[16,10037,10039],{"id":10038},"step-1-sign-up-with-github","Step 1: Sign Up With GitHub",[270,10041,10042,10060],{"gap":272,"left-width":4935,"right-width":4934},[277,10043,10044],{"v-slot:left":279},[20,10045,10046,10051,10054,10057],{},[23,10047,4412,10048],{},[39,10049,10050],{},"render.com",[23,10052,10053],{},"Choose GitHub sign-in",[23,10055,10056],{},"Authorize Render when prompted",[23,10058,10059],{},"Land on the Render dashboard",[277,10061,10062],{"v-slot:right":279},[53,10063,10064],{},[283,10065],{"alt":10066,"src":10067,"variant":287},"Render GitHub sign-in screen","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-01-github-signin.png",[11,10069,10071,10074],{"id":10070,"level":14},"step-2-new-web-service",[16,10072,10073],{"id":10070},"Step 2: New Web Service",[270,10075,10076,10096],{"gap":272,"left-width":4935,"right-width":4934},[277,10077,10078],{"v-slot:left":279},[20,10079,10080,10085,10090,10093],{},[23,10081,774,10082],{},[39,10083,10084],{},"New +",[23,10086,889,10087],{},[39,10088,10089],{},"Web Service",[23,10091,10092],{},"Do not choose a database service here",[23,10094,10095],{},"This creates the hosted PHP app",[277,10097,10098],{"v-slot:right":279},[53,10099,10100],{},[283,10101],{"alt":10102,"src":10103,"variant":287},"Render New menu with Web Service option","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-04-new-menu.png",[11,10105,10107,10111],{"id":10106,"level":14},"step-3-connect-repo",[16,10108,10110],{"id":10109},"step-3-connect-repository","Step 3: Connect Repository",[270,10112,10113,10133],{"gap":272,"left-width":274,"right-width":1591},[277,10114,10115],{"v-slot:left":279},[20,10116,10117,10120,10123,10130],{},[23,10118,10119],{},"Select your student course repository",[23,10121,10122],{},"Authorize repository access if Render asks",[23,10124,10125,10126,10129],{},"Ensure it's the proper repository (format: ",[39,10127,10128],{},"ucid-course-section-semYear",")",[23,10131,10132],{},"Continue to service settings",[277,10134,10135],{"v-slot:right":279},[53,10136,10137],{},[283,10138],{"alt":10139,"src":10140,"variant":287},"Render repository selection screen","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-07-select-repo.png",[11,10142,10144,10148],{"id":10143,"level":14},"step-4-configure-qa",[16,10145,10147],{"id":10146},"step-4-configure-qa-service","Step 4: Configure QA Service",[270,10149,10150,10183],{"gap":272,"left-width":4935,"right-width":4934},[277,10151,10152,10155],{"v-slot:left":279},[53,10153,10154],{},"Use these settings:",[20,10156,10157,10161,10166,10172,10177,10180],{},[23,10158,9990,10159],{},[39,10160,9993],{},[23,10162,10163,10164],{},"Branch: ",[39,10165,9113],{},[23,10167,10168,10169],{},"Runtime: ",[39,10170,10171],{},"Docker",[23,10173,10174,10175],{},"Instance type: ",[39,10176,9923],{},[23,10178,10179],{},"Root directory: blank",[23,10181,10182],{},"Build\u002Fstart commands: blank",[277,10184,10185],{"v-slot:right":279},[53,10186,10187],{},[283,10188],{"alt":10189,"src":10190,"variant":287},"Render QA service configuration","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-08-qa-config-basic.png",[11,10192,10194,10198],{"id":10193,"level":14},"step-5-env-vars",[16,10195,10197],{"id":10196},"step-5-add-environment-variables","Step 5: Add Environment Variables",[270,10199,10200,10229],{"gap":272,"left-width":484,"right-width":485},[277,10201,10202],{"v-slot:left":279},[20,10203,10204,10217,10223,10226],{},[23,10205,10206,10207,10209],{},"Add ",[39,10208,8675],{},[20,10210,10211],{},[23,10212,10213,10214],{},"Get it from ",[146,10215,8680],{"href":2205,"rel":10216},[150],[23,10218,10219,10220,10222],{},"Do not use \"add from ",[39,10221,8656],{},"\"",[23,10224,10225],{},"Add later API keys only when a later lesson requires them",[23,10227,10228],{},"Repeat required env vars on both QA and production",[277,10230,10231],{"v-slot:right":279},[53,10232,10233],{},[283,10234],{"alt":10235,"src":10236,"variant":287},"Render environment variables section","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-09-env-vars.png",[11,10238,10240,10243],{"id":10239,"level":14},"step-6-deploy-qa",[16,10241,10242],{"id":10239},"Step 6: Deploy QA",[270,10244,10245,10264],{"gap":272,"left-width":274,"right-width":1591},[277,10246,10247],{"v-slot:left":279},[20,10248,10249,10252,10255,10258,10261],{},[23,10250,10251],{},"Create the QA service",[23,10253,10254],{},"Watch the first deploy log",[23,10256,10257],{},"Wait for a success state",[23,10259,10260],{},"Open the QA URL",[23,10262,10263],{},"Confirm the starter page loads",[277,10265,10266],{"v-slot:right":279},[53,10267,10268],{},[283,10269],{"alt":10270,"src":10271,"variant":287},"Successful Render QA deployment","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-10-qa-deployed.png",[11,10273,10275,10279],{"id":10274,"level":14},"step-7-create-prod",[16,10276,10278],{"id":10277},"step-7-create-production-service","Step 7: Create Production Service",[270,10280,10281,10310],{"gap":272,"left-width":4935,"right-width":4934},[277,10282,10283,10286],{"v-slot:left":279},[53,10284,10285],{},"Create a second web service:",[20,10287,10288,10291,10295,10299,10303,10307],{},[23,10289,10290],{},"Same repository",[23,10292,9990,10293],{},[39,10294,10020],{},[23,10296,10163,10297],{},[39,10298,9116],{},[23,10300,10168,10301],{},[39,10302,10171],{},[23,10304,10174,10305],{},[39,10306,9923],{},[23,10308,10309],{},"Same required env vars",[277,10311,10312],{"v-slot:right":279},[53,10313,10314],{},[283,10315],{"alt":10316,"src":10317,"variant":287},"Render production service configuration","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-11-prod-config.png",[11,10319,10320,10323],{"id":9539,"level":14},[16,10321,10322],{"id":9539},"Normal Workflow",[2491,10324,10325,10328,10331,10336,10339,10342,10345,10352],{},[23,10326,10327],{},"Work locally on a feature or homework branch",[23,10329,10330],{},"Commit and push that branch to GitHub",[23,10332,10333,10334],{},"Open a pull request into ",[39,10335,9113],{},[23,10337,10338],{},"Merge after review",[23,10340,10341],{},"Render updates the QA URL",[23,10343,10344],{},"Test the QA URL",[23,10346,9605,10347,8867,10349,10351],{},[39,10348,9113],{},[39,10350,9116],{}," after evidence gathering",[23,10353,10354],{},"Render updates the production URL",[11,10356,10358,10361],{"id":10357,"level":14},"urls-and-cold-starts",[16,10359,10360],{"id":10357},"URLs And Cold Starts",[20,10362,10363,10366,10369,10372,10380],{},[23,10364,10365],{},"QA URL shows the test deployment",[23,10367,10368],{},"Production URL shows the stable deployment",[23,10370,10371],{},"Homework evidence usually starts with QA",[23,10373,10374,10375],{},"Free services may sleep after inactivity\n",[20,10376,10377],{},[23,10378,10379],{},"First visit after sleep may take extra time (2 - 5 minutes)",[23,10381,10382],{},"Do not submit before Render finishes deploying",[11,10384,10386,10389],{"id":10385,"level":14},"logs-and-status",[16,10387,10388],{"id":10385},"Logs And Status",[270,10390,10391,10407],{"gap":272,"left-width":274,"right-width":1591},[277,10392,10393],{"v-slot:left":279},[20,10394,10395,10398,10401,10404],{},[23,10396,10397],{},"Logs show build and startup output",[23,10399,10400],{},"Dashboard status shows deploy progress",[23,10402,10403],{},"Failed deploys usually show the first useful clue",[23,10405,10406],{},"Read the first clear error before changing settings",[277,10408,10409],{"v-slot:right":279},[53,10410,10411],{},[283,10412],{"alt":10413,"src":10414,"variant":287},"Render deploy logs","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-12-logs.png",[11,10416,10418,10421],{"id":10417,"level":14},"troubleshooting",[16,10419,10420],{"id":10417},"Troubleshooting",[20,10422,10423,10433,10441,10451],{},[23,10424,10425,10426],{},"Build fails\n",[20,10427,10428],{},[23,10429,1316,10430,10432],{},[39,10431,8324],{},", root directory, runtime, and instance type",[23,10434,10435,10436],{},"App deploys but page fails\n",[20,10437,10438],{},[23,10439,10440],{},"Check logs for PHP errors",[23,10442,10443,10444],{},"Database connection fails\n",[20,10445,10446],{},[23,10447,1316,10448,10450],{},[39,10449,8675],{}," spelling and copied value",[23,10452,10453,10454],{},"Wrong version appears\n",[20,10455,10456,10459],{},[23,10457,10458],{},"Confirm the service watches the expected branch",[23,10460,10461],{},"Clear browser cache or test in a private window",[11,10463,10464,10466],{"id":4107,"level":14},[16,10465,4110],{"id":4107},[20,10467,10468,10478,10481,10486,10489,10492],{},[23,10469,10470,10471,10473,10474,1574,10476],{},"Choosing ",[39,10472,4519],{}," instead of ",[39,10475,9113],{},[39,10477,9116],{},[23,10479,10480],{},"Creating one service for both environments",[23,10482,10483,10484],{},"Forgetting ",[39,10485,8675],{},[23,10487,10488],{},"Using a paid instance type by accident",[23,10490,10491],{},"Checking GitHub but not the Render URL",[23,10493,10494],{},"Changing code locally but forgetting to push and merge",[11,10496,10497,10499],{"id":2556,"level":14},[16,10498,2559],{"id":2556},[270,10500,10501,10529],{"gap":272,"left-width":1592,"right-width":1592},[277,10502,10503,10505,10511,10517,10523],{"v-slot:left":279},[2565,10504,2568],{"id":2567},[53,10506,10507,10510],{},[2572,10508,10509],{},"Service"," - one deployed app on Render",[53,10512,10513,10516],{},[2572,10514,10515],{},"Watched branch"," - Git branch Render deploys from",[53,10518,10519,10522],{},[2572,10520,10521],{},"Environment variable"," - setting stored outside code",[53,10524,10525,10528],{},[2572,10526,10527],{},"Deploy log"," - output from Render's build\u002Fstart process",[277,10530,10531,10533],{"v-slot:right":279},[2565,10532,2612],{"id":2611},[20,10534,10535,10542,10549,10556],{},[23,10536,10537],{},[146,10538,10541],{"href":10539,"rel":10540},"https:\u002F\u002Frender.com\u002Fdocs\u002Fweb-services",[150],"Render Docs: Web Services",[23,10543,10544],{},[146,10545,10548],{"href":10546,"rel":10547},"https:\u002F\u002Frender.com\u002Fdocs\u002Fdeploys",[150],"Render Docs: Deploys",[23,10550,10551],{},[146,10552,10555],{"href":10553,"rel":10554},"https:\u002F\u002Frender.com\u002Fdocs\u002Fconfigure-environment-variables",[150],"Render Docs: Environment Variables",[23,10557,10558],{},[146,10559,10562],{"href":10560,"rel":10561},"https:\u002F\u002Frender.com\u002Fdocs\u002Ffree",[150],"Render Docs: Free Instance Types",[11,10564,10565,10567,10570],{"id":2664,"level":14},[16,10566,2667],{"id":2664},[53,10568,10569],{},"Before leaving this presentation, confirm you:",[20,10571,10572,10575,10578,10585,10588,10591],{},[23,10573,10574],{},"Created QA and production Render services",[23,10576,10577],{},"Matched each service to the correct branch",[23,10579,10580,10581,8676,10583],{},"Added ",[39,10582,8675],{},[39,10584,8680],{},[23,10586,10587],{},"Opened each deployed URL",[23,10589,10590],{},"Read logs instead of assuming it worked",[23,10592,10593,10594],{},"Understand the local -> GitHub -> Render loop\n",[20,10595,10596,10599,10604],{},[23,10597,10598],{},"Majority of your work will be done locally and tested locally",[23,10600,10601,10603],{},[39,10602,9113],{}," is just for gathering evidence for submissions",[23,10605,10606,10608],{},[39,10607,9116],{}," is what will be verified during grading",{"title":279,"searchDepth":2694,"depth":2694,"links":10610},[10611,10612,10613,10614,10615,10616,10617,10618,10619,10620,10621,10622,10623,10624,10625,10626,10627,10628,10629],{"id":9830,"depth":2694,"text":9822},{"id":5229,"depth":2694,"text":5232},{"id":9877,"depth":2694,"text":9880},{"id":132,"depth":2694,"text":135},{"id":9974,"depth":2694,"text":9977},{"id":10038,"depth":2694,"text":10039},{"id":10070,"depth":2694,"text":10073},{"id":10109,"depth":2694,"text":10110},{"id":10146,"depth":2694,"text":10147},{"id":10196,"depth":2694,"text":10197},{"id":10239,"depth":2694,"text":10242},{"id":10277,"depth":2694,"text":10278},{"id":9539,"depth":2694,"text":10322},{"id":10357,"depth":2694,"text":10360},{"id":10385,"depth":2694,"text":10388},{"id":10417,"depth":2694,"text":10420},{"id":4107,"depth":2694,"text":4110},{"id":2556,"depth":2694,"text":2559},{"id":2664,"depth":2694,"text":2667},"Connect the course repository to Render, create QA and production services, and verify the deploy loop from GitHub to a live URL.","Face-to-face class of about 40 students; includes Render account setup, QA\u002Fprod service creation, environment variables, deploy verification, and first troubleshooting pass.",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup",{"title":9822,"description":10630},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup",[10637,10638,9113,9814],"render","deployment","21:42","esZd5RIpqCQ","https:\u002F\u002Fyoutu.be\u002FesZd5RIpqCQ","Render.com Setup (QA and Prod)","_1jV7vdhppggQ8TAOecx_1jFvjG90__8eGGlaXbnc28",{"id":4,"title":5,"audience":6,"body":10645,"contentType":2762,"course":2763,"description":2764,"estimateBasis":2765,"estimatedDiscussionMinutes":2766,"estimatedLiveMinutes":2767,"estimatedTotalMinutes":2768,"extension":871,"meta":12608,"module":569,"navigation":2770,"order":2771,"path":2772,"promptAssist":2773,"seo":12609,"status":2775,"stem":2776,"tags":12610,"videoDuration":2782,"videoId":2783,"videoLink":2784,"videoTitle":2785,"week":569,"__hash__":2786},{"type":8,"value":10646,"toc":12541},[10647,10667,10699,10725,10775,10797,10815,10839,10859,10881,10903,10923,10947,10969,10995,11041,11067,11101,11135,11169,11205,11247,11273,11299,11327,11351,11377,11401,11423,11445,11467,11489,11511,11537,11561,11585,11609,11645,11647,11677,11695,11725,11759,11817,11853,11875,11895,11915,11955,11973,12009,12043,12083,12125,12153,12175,12202,12226,12252,12290,12326,12338,12358,12390,12442,12519],[11,10648,10649,10651],{"id":13,"level":14},[16,10650,5],{"id":18},[20,10652,10653,10655,10657,10659,10661,10665],{},[23,10654,25],{},[23,10656,28],{},[23,10658,31],{},[23,10660,34],{},[23,10662,37,10663,42],{},[39,10664,41],{},[23,10666,45],{},[11,10668,10669,10671,10673,10681,10683],{"id":48,"level":14},[16,10670,51],{"id":48},[53,10672,55],{},[20,10674,10675,10677,10679],{},[23,10676,60],{},[23,10678,63],{},[23,10680,66],{},[53,10682,69],{},[20,10684,10685,10689,10693,10695,10697],{},[23,10686,74,10687],{},[39,10688,77],{},[23,10690,80,10691],{},[39,10692,41],{},[23,10694,85],{},[23,10696,88],{},[23,10698,91],{},[11,10700,10701,10703,10705,10719,10721],{"id":94,"level":14},[16,10702,97],{"id":94},[53,10704,100],{},[20,10706,10707,10709,10711,10717],{},[23,10708,105],{},[23,10710,108],{},[23,10712,111,10713],{},[20,10714,10715],{},[23,10716,116],{},[23,10718,119],{},[53,10720,122],{},[124,10722,10723],{"type":126},[53,10724,129],{},[11,10726,10727,10729],{"id":132,"level":14},[16,10728,135],{"id":132},[20,10730,10731,10744,10757,10759,10761,10763,10773],{},[23,10732,140,10733],{},[20,10734,10735,10740,10742],{},[23,10736,10737],{},[146,10738,151],{"href":148,"rel":10739},[150],[23,10741,154],{},[23,10743,157],{},[23,10745,160,10746],{},[20,10747,10748,10753,10755],{},[23,10749,10750],{},[146,10751,169],{"href":167,"rel":10752},[150],[23,10754,172],{},[23,10756,175],{},[23,10758,178],{},[23,10760,181],{},[23,10762,184],{},[23,10764,187,10765,191,10767],{},[39,10766,190],{},[20,10768,10769],{},[23,10770,10771,199],{},[39,10772,198],{},[23,10774,202],{},[11,10776,10777,10779],{"id":205,"level":14},[16,10778,208],{"id":205},[20,10780,10781,10783,10785,10787,10791,10793,10795],{},[23,10782,213],{},[23,10784,216],{},[23,10786,219],{},[23,10788,222,10789],{},[39,10790,225],{},[23,10792,228],{},[23,10794,231],{},[23,10796,234],{},[11,10798,10799,10801],{"id":237,"level":14},[16,10800,241],{"id":240},[20,10802,10803,10805,10807,10809,10811,10813],{},[23,10804,246],{},[23,10806,249],{},[23,10808,252],{},[23,10810,255],{},[23,10812,258],{},[23,10814,261],{},[11,10816,10817,10819],{"id":264,"level":265},[16,10818,268],{"id":264},[270,10820,10821,10827],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,10822,10823],{"v-slot:left":279},[53,10824,10825],{},[283,10826],{"alt":285,"src":286,"variant":287},[277,10828,10829],{"v-slot:right":279},[20,10830,10831,10835,10837],{},[23,10832,294,10833],{},[39,10834,297],{},[23,10836,300],{},[23,10838,303],{},[11,10840,10841,10843],{"id":306,"level":265},[16,10842,309],{"id":306},[270,10844,10845,10851],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,10846,10847],{"v-slot:left":279},[53,10848,10849],{},[283,10850],{"alt":318,"src":319,"variant":287},[277,10852,10853],{"v-slot:right":279},[20,10854,10855,10857],{},[23,10856,326],{},[23,10858,329],{},[11,10860,10861,10863],{"id":332,"level":265},[16,10862,335],{"id":332},[270,10864,10865,10871],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,10866,10867],{"v-slot:left":279},[53,10868,10869],{},[283,10870],{"alt":344,"src":345,"variant":287},[277,10872,10873],{"v-slot:right":279},[20,10874,10875,10877,10879],{},[23,10876,352],{},[23,10878,355],{},[23,10880,358],{},[11,10882,10883,10885],{"id":361,"level":265},[16,10884,364],{"id":361},[270,10886,10887,10893],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,10888,10889],{"v-slot:left":279},[53,10890,10891],{},[283,10892],{"alt":373,"src":374,"variant":287},[277,10894,10895],{"v-slot:right":279},[20,10896,10897,10899,10901],{},[23,10898,381],{},[23,10900,384],{},[23,10902,387],{},[11,10904,10905,10907],{"id":390,"level":265},[16,10906,394],{"id":393},[270,10908,10909,10915],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,10910,10911],{"v-slot:left":279},[53,10912,10913],{},[283,10914],{"alt":403,"src":404,"variant":287},[277,10916,10917],{"v-slot:right":279},[20,10918,10919,10921],{},[23,10920,411],{},[23,10922,414],{},[11,10924,10925,10927],{"id":417,"level":265},[16,10926,420],{"id":417},[270,10928,10929,10935],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,10930,10931],{"v-slot:left":279},[53,10932,10933],{},[283,10934],{"alt":429,"src":430,"variant":287},[277,10936,10937],{"v-slot:right":279},[20,10938,10939,10941],{},[23,10940,437],{},[23,10942,440,10943],{},[20,10944,10945],{},[23,10946,445],{},[11,10948,10949,10951],{"id":448,"level":265},[16,10950,451],{"id":448},[270,10952,10953,10959],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,10954,10955],{"v-slot:left":279},[53,10956,10957],{},[283,10958],{"alt":460,"src":461,"variant":287},[277,10960,10961],{"v-slot:right":279},[20,10962,10963,10965,10967],{},[23,10964,468],{},[23,10966,471],{},[23,10968,474],{},[11,10970,10971,10973],{"id":477,"level":14},[16,10972,481],{"id":480},[270,10974,10975,10989],{"gap":272,"left-width":484,"right-width":485,"stack":275},[277,10976,10977],{"v-slot:left":279},[20,10978,10979,10981,10983,10985,10987],{},[23,10980,492],{},[23,10982,495],{},[23,10984,498],{},[23,10986,501],{},[23,10988,504],{},[277,10990,10991],{"v-slot:right":279},[53,10992,10993],{},[283,10994],{"alt":511,"src":512,"variant":287},[11,10996,10997,10999,11001],{"id":515,"level":14},[16,10998,519],{"id":518},[53,11000,522],{},[20,11002,11003,11005,11011,11021,11031,11035,11037,11039],{},[23,11004,527],{},[23,11006,530,11007],{},[20,11008,11009],{},[23,11010,535],{},[23,11012,538,11013,542,11015],{},[39,11014,541],{},[20,11016,11017],{},[23,11018,547,11019,551],{},[39,11020,550],{},[23,11022,554,11023,557,11025],{},[39,11024,190],{},[20,11026,11027],{},[23,11028,11029,199],{},[39,11030,198],{},[23,11032,566,11033,570],{},[39,11034,569],{},[23,11036,573],{},[23,11038,576],{},[23,11040,579],{},[11,11042,11043,11045],{"id":582,"level":265},[16,11044,585],{"id":582},[270,11046,11047,11053],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,11048,11049],{"v-slot:left":279},[53,11050,11051],{},[283,11052],{"alt":594,"src":595,"variant":287},[277,11054,11055],{"v-slot:right":279},[20,11056,11057,11059,11063,11065],{},[23,11058,602],{},[23,11060,605,11061],{},[39,11062,608],{},[23,11064,611],{},[23,11066,614],{},[11,11068,11069,11071],{"id":617,"level":265},[16,11070,620],{"id":617},[270,11072,11073,11079],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,11074,11075],{"v-slot:left":279},[53,11076,11077],{},[283,11078],{"alt":629,"src":630,"variant":287},[277,11080,11081],{"v-slot:right":279},[20,11082,11083,11087,11091,11093],{},[23,11084,637,11085],{},[39,11086,640],{},[23,11088,643,11089],{},[39,11090,646],{},[23,11092,649],{},[23,11094,652,11095,656,11097],{},[39,11096,655],{},[20,11098,11099],{},[23,11100,661],{},[11,11102,11103,11105],{"id":664,"level":265},[16,11104,667],{"id":664},[270,11106,11107,11113],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,11108,11109],{"v-slot:left":279},[53,11110,11111],{},[283,11112],{"alt":676,"src":677,"variant":287},[277,11114,11115],{"v-slot:right":279},[20,11116,11117,11127,11131,11133],{},[23,11118,538,11119,542,11121],{},[39,11120,686],{},[20,11122,11123,11125],{},[23,11124,691],{},[23,11126,694],{},[23,11128,566,11129],{},[39,11130,569],{},[23,11132,701],{},[23,11134,704],{},[11,11136,11137,11139],{"id":707,"level":265},[16,11138,710],{"id":707},[270,11140,11141,11147],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,11142,11143],{"v-slot:left":279},[53,11144,11145],{},[283,11146],{"alt":719,"src":720,"variant":287},[277,11148,11149],{"v-slot:right":279},[20,11150,11151,11155,11157,11167],{},[23,11152,727,11153],{},[39,11154,730],{},[23,11156,733],{},[23,11158,736,11159,11161],{},[39,11160,190],{},[20,11162,11163],{},[23,11164,11165,745],{},[39,11166,198],{},[23,11168,748],{},[11,11170,11171,11173],{"id":751,"level":265},[16,11172,754],{"id":751},[270,11174,11175,11181],{"gap":272,"left-width":273,"right-width":274,"stack":275},[277,11176,11177],{"v-slot:left":279},[53,11178,11179],{},[283,11180],{"alt":763,"src":764,"variant":287},[277,11182,11183],{"v-slot:right":279},[20,11184,11185,11187,11195,11197],{},[23,11186,771],{},[23,11188,774,11189,11191],{},[39,11190,777],{},[20,11192,11193],{},[23,11194,782],{},[23,11196,785],{},[23,11198,788,11199],{},[20,11200,11201],{},[23,11202,793,11203,797],{},[39,11204,796],{},[11,11206,11207,11209,11211],{"id":800,"level":14},[16,11208,804],{"id":803},[53,11210,807],{},[20,11212,11213,11215,11217,11219,11221,11223,11245],{},[23,11214,812],{},[23,11216,815],{},[23,11218,818],{},[23,11220,821],{},[23,11222,824],{},[23,11224,827,11225],{},[20,11226,11227,11231,11237,11241],{},[23,11228,11229,836],{},[833,11230,835],{},[23,11232,11233,842,11235,846],{},[833,11234,841],{},[833,11236,845],{},[23,11238,11239,852],{},[833,11240,851],{},[23,11242,11243,858],{},[833,11244,857],{},[23,11246,861],{},[11,11248,11249,11251],{"id":864,"level":265},[16,11250,868],{"id":867},[270,11252,11253,11259],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11254,11255],{"v-slot:left":279},[53,11256,11257],{},[283,11258],{"alt":880,"src":881,"variant":882},[277,11260,11261],{"v-slot:right":279},[20,11262,11263,11267,11271],{},[23,11264,889,11265],{},[39,11266,892],{},[23,11268,895,11269],{},[833,11270,857],{},[23,11272,900],{},[11,11274,11275,11277],{"id":903,"level":265},[16,11276,907],{"id":906},[270,11278,11279,11285],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11280,11281],{"v-slot:left":279},[53,11282,11283],{},[283,11284],{"alt":916,"src":917,"variant":882},[277,11286,11287],{"v-slot:right":279},[20,11288,11289,11291,11295],{},[23,11290,924],{},[23,11292,11293,930],{},[39,11294,929],{},[23,11296,895,11297,935],{},[833,11298,857],{},[11,11300,11301,11303],{"id":938,"level":265},[16,11302,942],{"id":941},[270,11304,11305,11311],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11306,11307],{"v-slot:left":279},[53,11308,11309],{},[283,11310],{"alt":951,"src":952,"variant":882},[277,11312,11313],{"v-slot:right":279},[20,11314,11315,11323,11325],{},[23,11316,889,11317,11319],{},[39,11318,961],{},[20,11320,11321],{},[23,11322,966],{},[23,11324,969],{},[23,11326,972],{},[11,11328,11329,11331],{"id":975,"level":265},[16,11330,979],{"id":978},[270,11332,11333,11339],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11334,11335],{"v-slot:left":279},[53,11336,11337],{},[283,11338],{"alt":988,"src":989,"variant":882},[277,11340,11341],{"v-slot:right":279},[20,11342,11343,11345,11349],{},[23,11344,996],{},[23,11346,999,11347],{},[39,11348,1002],{},[23,11350,1005],{},[11,11352,11353,11355],{"id":1008,"level":265},[16,11354,1012],{"id":1011},[270,11356,11357,11363],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11358,11359],{"v-slot:left":279},[53,11360,11361],{},[283,11362],{"alt":1021,"src":1022,"variant":882},[277,11364,11365],{"v-slot:right":279},[20,11366,11367,11373,11375],{},[23,11368,1029,11369,1033,11371],{},[39,11370,1032],{},[39,11372,1036],{},[23,11374,1039],{},[23,11376,1042],{},[11,11378,11379,11381],{"id":1045,"level":265},[16,11380,1049],{"id":1048},[270,11382,11383,11389],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11384,11385],{"v-slot:left":279},[53,11386,11387],{},[283,11388],{"alt":1058,"src":1059,"variant":882},[277,11390,11391],{"v-slot:right":279},[20,11392,11393,11395,11399],{},[23,11394,1066],{},[23,11396,11397,1072],{},[39,11398,1071],{},[23,11400,1075],{},[11,11402,11403,11405],{"id":1078,"level":265},[16,11404,1082],{"id":1081},[270,11406,11407,11413],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11408,11409],{"v-slot:left":279},[53,11410,11411],{},[283,11412],{"alt":1091,"src":1092,"variant":882},[277,11414,11415],{"v-slot:right":279},[20,11416,11417,11419,11421],{},[23,11418,1099],{},[23,11420,1102],{},[23,11422,1105],{},[11,11424,11425,11427],{"id":1108,"level":265},[16,11426,1112],{"id":1111},[270,11428,11429,11435],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11430,11431],{"v-slot:left":279},[53,11432,11433],{},[283,11434],{"alt":1121,"src":1122,"variant":882},[277,11436,11437],{"v-slot:right":279},[20,11438,11439,11441,11443],{},[23,11440,1129],{},[23,11442,1132],{},[23,11444,1135],{},[11,11446,11447,11449],{"id":1138,"level":265},[16,11448,1142],{"id":1141},[270,11450,11451,11457],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11452,11453],{"v-slot:left":279},[53,11454,11455],{},[283,11456],{"alt":1151,"src":1152,"variant":882},[277,11458,11459],{"v-slot:right":279},[20,11460,11461,11463,11465],{},[23,11462,1159],{},[23,11464,1162],{},[23,11466,1165],{},[11,11468,11469,11471],{"id":1168,"level":265},[16,11470,1172],{"id":1171},[270,11472,11473,11479],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11474,11475],{"v-slot:left":279},[53,11476,11477],{},[283,11478],{"alt":1181,"src":1182,"variant":882},[277,11480,11481],{"v-slot:right":279},[20,11482,11483,11485,11487],{},[23,11484,1189],{},[23,11486,1192],{},[23,11488,1195],{},[11,11490,11491,11493],{"id":1198,"level":265},[16,11492,1202],{"id":1201},[270,11494,11495,11501],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11496,11497],{"v-slot:left":279},[53,11498,11499],{},[283,11500],{"alt":1211,"src":1212,"variant":882},[277,11502,11503],{"v-slot:right":279},[20,11504,11505,11507,11509],{},[23,11506,1219],{},[23,11508,1222],{},[23,11510,1225],{},[11,11512,11513,11515],{"id":1228,"level":265},[16,11514,1232],{"id":1231},[270,11516,11517,11523],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11518,11519],{"v-slot:left":279},[53,11520,11521],{},[283,11522],{"alt":1241,"src":1242,"variant":882},[277,11524,11525],{"v-slot:right":279},[20,11526,11527,11529,11533,11535],{},[23,11528,1249],{},[23,11530,1252,11531],{},[39,11532,608],{},[23,11534,1257],{},[23,11536,1260],{},[11,11538,11539,11541],{"id":1263,"level":265},[16,11540,1267],{"id":1266},[270,11542,11543,11549],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11544,11545],{"v-slot:left":279},[53,11546,11547],{},[283,11548],{"alt":1276,"src":1277,"variant":882},[277,11550,11551],{"v-slot:right":279},[20,11552,11553,11557,11559],{},[23,11554,889,11555],{},[39,11556,1286],{},[23,11558,1289],{},[23,11560,1292],{},[11,11562,11563,11565],{"id":1295,"level":265},[16,11564,1299],{"id":1298},[270,11566,11567,11573],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11568,11569],{"v-slot:left":279},[53,11570,11571],{},[283,11572],{"alt":1308,"src":1309,"variant":882},[277,11574,11575],{"v-slot:right":279},[20,11576,11577,11581,11583],{},[23,11578,1316,11579],{},[39,11580,1319],{},[23,11582,1322],{},[23,11584,1325],{},[11,11586,11587,11589],{"id":1328,"level":265},[16,11588,1332],{"id":1331},[270,11590,11591,11597],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11592,11593],{"v-slot:left":279},[53,11594,11595],{},[283,11596],{"alt":1341,"src":1342,"variant":882},[277,11598,11599],{"v-slot:right":279},[20,11600,11601,11603,11607],{},[23,11602,1349],{},[23,11604,1352,11605],{},[39,11606,1355],{},[23,11608,1358],{},[11,11610,11611,11613],{"id":1361,"level":265},[16,11612,1365],{"id":1364},[270,11614,11615,11621],{"gap":871,"left-width":872,"right-width":873,"stack":275},[277,11616,11617],{"v-slot:left":279},[53,11618,11619],{},[283,11620],{"alt":1374,"src":1375,"variant":882},[277,11622,11623,11641],{"v-slot:right":279},[20,11624,11625,11627,11629,11635,11639],{},[23,11626,1382],{},[23,11628,1385],{},[23,11630,1388,11631,1391,11633],{},[39,11632,541],{},[39,11634,550],{},[23,11636,1396,11637,1399],{},[39,11638,541],{},[23,11640,1402],{},[124,11642,11643],{"type":126},[53,11644,1407],{},[53,11646,1410],{},[11,11648,11649,11651,11653],{"id":1413,"level":14},[16,11650,1417],{"id":1416},[53,11652,1420],{},[20,11654,11655,11659,11665,11671,11675],{},[23,11656,1425,11657],{},[39,11658,1428],{},[23,11660,1431,11661,1435,11663],{},[39,11662,1434],{},[39,11664,1434],{},[23,11666,1440,11667,1435,11669],{},[39,11668,1443],{},[39,11670,1446],{},[23,11672,547,11673,1451],{},[39,11674,225],{},[23,11676,1454],{},[11,11678,11679,11681,11691],{"id":1457,"level":265},[16,11680,1461],{"id":1460},[20,11682,11683,11685,11689],{},[23,11684,1466],{},[23,11686,1469,11687],{},[39,11688,1428],{},[23,11690,1474],{},[53,11692,11693],{},[283,11694],{"alt":1479,"src":1480,"variant":882},[11,11696,11697,11699,11721],{"id":1483,"level":265},[16,11698,1487],{"id":1486},[20,11700,11701,11707,11713],{},[23,11702,1492,11703,1495,11705],{},[39,11704,1434],{},[39,11706,1434],{},[23,11708,1500,11709,1495,11711],{},[39,11710,1443],{},[39,11712,1446],{},[23,11714,1507,11715,1510,11717,1495,11719],{},[39,11716,1434],{},[39,11718,1513],{},[39,11720,1434],{},[53,11722,11723],{},[283,11724],{"alt":1520,"src":1521,"variant":882},[11,11726,11727,11729,11731,11733,11735,11737],{"id":1524,"level":14},[16,11728,1528],{"id":1527},[53,11730,1531],{},[1533,11732],{"language":1535,"src":1536},[53,11734,1539],{},[1533,11736],{"language":1542,"src":1543},[20,11738,11739,11743,11749,11751,11753],{},[23,11740,1548,11741,1552],{},[39,11742,1551],{},[23,11744,1555,11745,1559,11747,1562],{},[39,11746,1558],{},[39,11748,225],{},[23,11750,1565],{},[23,11752,1568],{},[23,11754,11755,1574,11757,1578],{},[39,11756,1573],{},[39,11758,1577],{},[11,11760,11761,11763,11765],{"id":1581,"level":14},[16,11762,1585],{"id":1584},[53,11764,1588],{},[270,11766,11767,11797],{"gap":272,"left-width":1591,"right-width":1592,"stack":275},[277,11768,11769,11771,11773],{"v-slot:left":279},[53,11770,1597],{},[1533,11772],{"language":1535,"src":1600},[20,11774,11775,11779,11783,11787,11791],{},[23,11776,11777,1608],{},[39,11778,1607],{},[23,11780,11781,1614],{},[39,11782,1613],{},[23,11784,11785,1620],{},[39,11786,1619],{},[23,11788,11789,1626],{},[39,11790,1625],{},[23,11792,1629,11793,1632,11795],{},[39,11794,1607],{},[39,11796,1635],{},[277,11798,11799,11801,11803],{"v-slot:right":279},[53,11800,1640],{},[1533,11802],{"language":1535,"src":1643},[20,11804,11805,11809,11811,11815],{},[23,11806,1648,11807],{},[39,11808,1071],{},[23,11810,1653],{},[23,11812,547,11813,1451],{},[39,11814,225],{},[23,11816,1660],{},[11,11818,11819,11821],{"id":1663,"level":14},[16,11820,1667],{"id":1666},[270,11822,11823,11847],{"gap":272,"left-width":274,"right-width":1591,"stack":275},[277,11824,11825,11827],{"v-slot:left":279},[53,11826,1674],{},[20,11828,11829,11831,11833,11835,11837,11839,11841,11843,11845],{},[23,11830,1679],{},[23,11832,1682],{},[23,11834,1685],{},[23,11836,1688],{},[23,11838,1691],{},[23,11840,1694],{},[23,11842,1697],{},[23,11844,1700],{},[23,11846,1703],{},[277,11848,11849],{"v-slot:right":279},[53,11850,11851],{},[283,11852],{"alt":1710,"src":1711,"variant":287},[11,11854,11855,11857,11859,11861],{"id":1714,"level":14},[16,11856,1718],{"id":1717},[53,11858,1721],{},[1533,11860],{"language":1535,"src":1724},[20,11862,11863,11869,11873],{},[23,11864,1729,11865,1732,11867,1735],{},[39,11866,1619],{},[39,11868,1625],{},[23,11870,11871,1741],{},[39,11872,1740],{},[23,11874,1744],{},[11,11876,11877,11879,11881,11883],{"id":1747,"level":265},[16,11878,1751],{"id":1750},[53,11880,1754],{},[1533,11882],{"language":1535,"src":1757},[20,11884,11885,11889,11893],{},[23,11886,11887,1765],{},[39,11888,1764],{},[23,11890,11891,1771],{},[39,11892,1770],{},[23,11894,1774],{},[11,11896,11897,11899,11901,11903],{"id":1777,"level":14},[16,11898,1781],{"id":1780},[53,11900,1784],{},[1533,11902],{"language":1535,"src":1787},[20,11904,11905,11909,11913],{},[23,11906,11907,1795],{},[39,11908,1794],{},[23,11910,11911,1801],{},[39,11912,1800],{},[23,11914,1804],{},[11,11916,11917,11919,11921,11923,11935,11937],{"id":1807,"level":265},[16,11918,1811],{"id":1810},[53,11920,1754],{},[1533,11922],{"language":1535,"src":1816},[20,11924,11925,11929,11933],{},[23,11926,11927,1824],{},[39,11928,1823],{},[23,11930,11931,1830],{},[39,11932,1829],{},[23,11934,1833],{},[53,11936,1836],{},[20,11938,11939,11943,11947,11951],{},[23,11940,11941],{},[39,11942,41],{},[23,11944,11945],{},[39,11946,1847],{},[23,11948,11949],{},[39,11950,1852],{},[23,11952,11953],{},[39,11954,1857],{},[11,11956,11957,11959,11971],{"id":1860,"level":265},[16,11958,1864],{"id":1863},[20,11960,11961,11963,11969],{},[23,11962,1869],{},[23,11964,1729,11965,1574,11967,1878],{},[39,11966,1874],{},[39,11968,1877],{},[23,11970,1881],{},[53,11972,1884],{},[11,11974,11975,11977,11979,11981],{"id":1887,"level":14},[16,11976,1891],{"id":1890},[53,11978,1721],{},[1533,11980],{"language":1535,"src":1896},[20,11982,11983,11987,11991,11995,11999,12003],{},[23,11984,11985,1904],{},[39,11986,1903],{},[23,11988,11989,1910],{},[39,11990,1909],{},[23,11992,11993,1916],{},[39,11994,1915],{},[23,11996,11997,1922],{},[39,11998,1921],{},[23,12000,12001,1928],{},[39,12002,1927],{},[23,12004,1729,12005,1732,12007,1935],{},[39,12006,1619],{},[39,12008,1625],{},[11,12010,12011,12013,12017],{"id":1938,"level":265},[16,12012,1942],{"id":1941},[53,12014,1945,12015,1949],{},[39,12016,1948],{},[270,12018,12019,12029],{"gap":272,"left-width":1592,"right-width":1592},[277,12020,12021,12023,12025,12027],{"v-slot:left":279},[53,12022,1956],{},[1533,12024],{"language":1535,"src":1959},[53,12026,1962],{},[1533,12028],{"language":1535,"src":1965},[277,12030,12031],{"v-slot:right":279},[20,12032,12033,12035,12039,12041],{},[23,12034,1972],{},[23,12036,1975,12037],{},[39,12038,541],{},[23,12040,1980],{},[23,12042,1983],{},[11,12044,12045,12047,12051],{"id":1986,"level":265},[16,12046,1990],{"id":1989},[53,12048,1993,12049,1996],{},[39,12050,541],{},[270,12052,12053,12063],{"gap":272,"left-width":1592,"right-width":1592},[277,12054,12055,12057,12061],{"v-slot:left":279},[53,12056,2003],{},[53,12058,12059],{},[39,12060,2008],{},[1533,12062],{"language":1535,"src":2011},[277,12064,12065,12067,12069],{"v-slot:right":279},[53,12066,2016],{},[1533,12068],{"language":2019,"src":2020},[20,12070,12071,12075,12077,12081],{},[23,12072,2025,12073],{},[39,12074,2028],{},[23,12076,2031],{},[23,12078,2034,12079,2038],{},[39,12080,2037],{},[23,12082,2041],{},[11,12084,12085,12087,12091],{"id":2044,"level":265},[16,12086,2048],{"id":2047},[53,12088,2051,12089,2054],{},[39,12090,541],{},[270,12092,12093,12103],{"gap":272,"left-width":1592,"right-width":1592},[277,12094,12095,12097,12101],{"v-slot:left":279},[53,12096,2061],{},[53,12098,12099],{},[39,12100,2066],{},[1533,12102],{"language":1535,"src":2069},[277,12104,12105,12109,12111],{"v-slot:right":279},[53,12106,2074,12107,2078],{},[39,12108,2077],{},[1533,12110],{"language":2081,"src":2082},[20,12112,12113,12117,12121,12123],{},[23,12114,2087,12115,2090],{},[39,12116,2077],{},[23,12118,2093,12119,2090],{},[39,12120,2077],{},[23,12122,2098],{},[23,12124,2101],{},[11,12126,12127,12129,12131,12133],{"id":2104,"level":265},[16,12128,2107],{"id":2104},[53,12130,2110],{},[1533,12132],{"language":1535,"src":2113},[20,12134,12135,12139,12143,12147,12151],{},[23,12136,12137,2121],{},[39,12138,2120],{},[23,12140,12141,2126],{},[39,12142,1948],{},[23,12144,12145,2132],{},[39,12146,2131],{},[23,12148,2135,12149,2139],{},[39,12150,2138],{},[23,12152,2142],{},[11,12154,12155,12157,12159,12161,12163,12165],{"id":2145,"level":14},[16,12156,2149],{"id":2148},[53,12158,1721],{},[1533,12160],{"language":1535,"src":2154},[53,12162,2157],{},[1533,12164],{"language":1857,"src":2160},[20,12166,12167,12171,12173],{},[23,12168,1548,12169,1552],{},[39,12170,1551],{},[23,12172,2169],{},[23,12174,2172],{},[11,12176,12177,12179,12181,12193,12195,12200],{"id":2175,"level":14},[16,12178,2178],{"id":2175},[53,12180,2181],{},[20,12182,12183,12187,12189,12191],{},[23,12184,2186,12185],{},[39,12186,225],{},[23,12188,2191],{},[23,12190,1257],{},[23,12192,2196],{},[53,12194,2199],{},[53,12196,2202,12197],{},[146,12198,2205],{"href":2205,"rel":12199},[150],[53,12201,2209],{},[11,12203,12204,12206,12208,12210,12212,12214,12216],{"id":2212,"level":14},[16,12205,2216],{"id":2215},[53,12207,1721],{},[1533,12209],{"language":1535,"src":2221},[53,12211,2224],{},[1533,12213],{"language":1857,"src":2227},[53,12215,2230],{},[20,12217,12218,12222],{},[23,12219,12220,2238],{},[39,12221,2237],{},[23,12223,12224,2244],{},[39,12225,2243],{},[11,12227,12228,12232,12234,12236,12238],{"id":2247,"level":14},[16,12229,2251,12230],{"id":2250},[39,12231,41],{},[53,12233,2256],{},[1533,12235],{"language":1542,"src":2259},[53,12237,2262],{},[20,12239,12240,12248],{},[23,12241,12242,2269,12244,2272,12246,2275],{},[39,12243,1847],{},[39,12245,1852],{},[39,12247,1857],{},[23,12249,12250,2280],{},[39,12251,41],{},[11,12253,12254,12256,12258,12262,12264,12268,12270,12272],{"id":2283,"level":265},[16,12255,2287],{"id":2286},[53,12257,2290],{},[53,12259,12260],{},[39,12261,2295],{},[53,12263,2298],{},[53,12265,12266],{},[39,12267,2303],{},[53,12269,2306],{},[1533,12271],{"language":2019,"src":2309},[20,12273,12274,12278,12282,12286],{},[23,12275,1548,12276,2316],{},[39,12277,1829],{},[23,12279,2319,12280],{},[39,12281,2322],{},[23,12283,2325,12284],{},[39,12285,1446],{},[23,12287,2330,12288],{},[39,12289,77],{},[11,12291,12292,12294,12296,12298],{"id":2335,"level":265},[16,12293,2339],{"id":2338},[53,12295,1721],{},[1533,12297],{"language":1535,"src":2344},[20,12299,12300,12304,12308,12312,12318,12322],{},[23,12301,12302,2352],{},[39,12303,2351],{},[23,12305,12306,2358],{},[39,12307,2357],{},[23,12309,12310,2364],{},[39,12311,2363],{},[23,12313,2367,12314,2370,12316,2373],{},[39,12315,2363],{},[39,12317,1794],{},[23,12319,12320,2379],{},[39,12321,2378],{},[23,12323,12324,2385],{},[39,12325,2384],{},[11,12327,12328,12330,12332,12334,12336],{"id":2388,"level":14},[16,12329,2392],{"id":2391},[53,12331,2395],{},[1533,12333],{"language":1542,"src":2398},[53,12335,2401],{},[1533,12337],{"language":1909,"src":2404},[11,12339,12340,12342,12344,12346,12348],{"id":2407,"level":14},[16,12341,2410],{"id":2407},[53,12343,2413],{},[1533,12345],{"language":1542,"src":2416},[53,12347,2230],{},[20,12349,12350,12352,12354,12356],{},[23,12351,2423],{},[23,12353,2426],{},[23,12355,2429],{},[23,12357,2432],{},[11,12359,12360,12362],{"id":2435,"level":14},[16,12361,2438],{"id":2435},[20,12363,12364,12366,12368,12372,12374,12382,12388],{},[23,12365,2443],{},[23,12367,2446],{},[23,12369,2449,12370],{},[39,12371,1428],{},[23,12373,2454],{},[23,12375,2457,12376,2461,12378,2464,12380,2467],{},[39,12377,2460],{},[39,12379,2363],{},[39,12381,1794],{},[23,12383,2470,12384,2474,12386,2477],{},[39,12385,2473],{},[39,12387,1794],{},[23,12389,2480],{},[11,12391,12392,12394,12396],{"id":2483,"level":14},[16,12393,2486],{"id":2483},[53,12395,2489],{},[2491,12397,12398,12400,12404,12408,12412,12418,12424,12428,12432,12438],{},[23,12399,2495],{},[23,12401,12402,2501],{},[39,12403,2500],{},[23,12405,12406,2507],{},[39,12407,2506],{},[23,12409,12410,2512],{},[39,12411,1770],{},[23,12413,12414,2518,12416],{},[39,12415,2517],{},[39,12417,1794],{},[23,12419,12420,2518,12422],{},[39,12421,2525],{},[39,12423,1794],{},[23,12425,12426,2533],{},[39,12427,2532],{},[23,12429,12430,2533],{},[39,12431,2538],{},[23,12433,12434,2544,12436],{},[39,12435,2543],{},[39,12437,2547],{},[23,12439,12440,2553],{},[39,12441,2552],{},[11,12443,12444,12446],{"id":2556,"level":14},[16,12445,2559],{"id":2556},[270,12447,12448,12478],{"gap":272,"left-width":1592,"right-width":1592},[277,12449,12450,12452,12456,12462,12466,12470,12474],{"v-slot:left":279},[2565,12451,2568],{"id":2567},[53,12453,12454,2575],{},[2572,12455,2574],{},[53,12457,12458,2581,12460,2584],{},[2572,12459,2580],{},[39,12461,225],{},[53,12463,12464,2589],{},[2572,12465,1794],{},[53,12467,12468,2595],{},[2572,12469,2594],{},[53,12471,12472,2601],{},[2572,12473,2600],{},[53,12475,12476,2606],{},[2572,12477,1428],{},[277,12479,12480,12482],{"v-slot:right":279},[2565,12481,2612],{"id":2611},[20,12483,12484,12489,12494,12499,12504,12509,12514],{},[23,12485,12486],{},[146,12487,2620],{"href":148,"rel":12488},[150],[23,12490,12491],{},[146,12492,2627],{"href":2625,"rel":12493},[150],[23,12495,12496],{},[146,12497,2634],{"href":2632,"rel":12498},[150],[23,12500,12501],{},[146,12502,2641],{"href":2639,"rel":12503},[150],[23,12505,12506],{},[146,12507,2648],{"href":2646,"rel":12508},[150],[23,12510,12511],{},[146,12512,2654],{"href":167,"rel":12513},[150],[23,12515,12516],{},[146,12517,2661],{"href":2659,"rel":12518},[150],[11,12520,12521,12523,12525],{"id":2664,"level":14},[16,12522,2667],{"id":2664},[53,12524,2670],{},[20,12526,12527,12529,12531,12533,12535,12539],{},[23,12528,2675],{},[23,12530,2678],{},[23,12532,2681],{},[23,12534,2684],{},[23,12536,2687,12537],{},[39,12538,41],{},[23,12540,2692],{},{"title":279,"searchDepth":2694,"depth":2694,"links":12542},[12543,12544,12545,12546,12547,12548,12549,12550,12551,12552,12553,12554,12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,12583,12584,12585,12586,12587,12588,12589,12590,12591,12592,12593,12594,12595,12596,12597,12598,12599,12600,12601,12602,12603,12604,12605,12606,12607],{"id":18,"depth":2694,"text":5},{"id":48,"depth":2694,"text":51},{"id":94,"depth":2694,"text":97},{"id":132,"depth":2694,"text":135},{"id":205,"depth":2694,"text":208},{"id":240,"depth":2694,"text":241},{"id":264,"depth":2694,"text":268},{"id":306,"depth":2694,"text":309},{"id":332,"depth":2694,"text":335},{"id":361,"depth":2694,"text":364},{"id":393,"depth":2694,"text":394},{"id":417,"depth":2694,"text":420},{"id":448,"depth":2694,"text":451},{"id":480,"depth":2694,"text":481},{"id":518,"depth":2694,"text":519},{"id":582,"depth":2694,"text":585},{"id":617,"depth":2694,"text":620},{"id":664,"depth":2694,"text":667},{"id":707,"depth":2694,"text":710},{"id":751,"depth":2694,"text":754},{"id":803,"depth":2694,"text":804},{"id":867,"depth":2694,"text":868},{"id":906,"depth":2694,"text":907},{"id":941,"depth":2694,"text":942},{"id":978,"depth":2694,"text":979},{"id":1011,"depth":2694,"text":1012},{"id":1048,"depth":2694,"text":1049},{"id":1081,"depth":2694,"text":1082},{"id":1111,"depth":2694,"text":1112},{"id":1141,"depth":2694,"text":1142},{"id":1171,"depth":2694,"text":1172},{"id":1201,"depth":2694,"text":1202},{"id":1231,"depth":2694,"text":1232},{"id":1266,"depth":2694,"text":1267},{"id":1298,"depth":2694,"text":1299},{"id":1331,"depth":2694,"text":1332},{"id":1364,"depth":2694,"text":1365},{"id":1416,"depth":2694,"text":1417},{"id":1460,"depth":2694,"text":1461},{"id":1486,"depth":2694,"text":1487},{"id":1527,"depth":2694,"text":1528},{"id":1584,"depth":2694,"text":1585},{"id":1666,"depth":2694,"text":1667},{"id":1717,"depth":2694,"text":1718},{"id":1750,"depth":2694,"text":1751},{"id":1780,"depth":2694,"text":1781},{"id":1810,"depth":2694,"text":1811},{"id":1863,"depth":2694,"text":1864},{"id":1890,"depth":2694,"text":1891},{"id":1941,"depth":2694,"text":1942},{"id":1989,"depth":2694,"text":1990},{"id":2047,"depth":2694,"text":2048},{"id":2104,"depth":2694,"text":2107},{"id":2148,"depth":2694,"text":2149},{"id":2175,"depth":2694,"text":2178},{"id":2215,"depth":2694,"text":2216},{"id":2250,"depth":2694,"text":2753},{"id":2286,"depth":2694,"text":2287},{"id":2338,"depth":2694,"text":2339},{"id":2391,"depth":2694,"text":2392},{"id":2407,"depth":2694,"text":2410},{"id":2435,"depth":2694,"text":2438},{"id":2483,"depth":2694,"text":2486},{"id":2556,"depth":2694,"text":2559},{"id":2664,"depth":2694,"text":2667},{},{"title":5,"description":2764},[2778,2779,2019,2780,2781],[],1780581681553]