1"use strict"; 2angular 3 .module("sfmStore", [ 4 "ui.router", 5 "ui.bootstrap", 6 "ngStorage", 7 "credit-cards", 8 "ncy-angular-breadcrumb", 9 "formly", 10 "formlyBootstrap", 11 "paypal-buttons" 12 ]) 13 .run(function( 14 APP_CONFIG, 15 $rootScope, 16 $window, 17 $location, 18 $state, 19 $profile, 20 $order, 21 $products, 22 formlyConfig, 23 $localStorage 24 ) { 25 var appRoot = APP_CONFIG.APP_ROOT; 26 //Bind the `$locationChangeSuccess` event on the rootScope, so that we dont need to 27 //bind in induvidual controllers. 28 29 $rootScope.$on("$locationChangeSuccess", function() { 30 $rootScope.actualLocation = $location.path(); 31 }); 32 33 $rootScope.$watch( 34 function() { 35 return $location.path(); 36 }, 37 function(newLocation, oldLocation) { 38 if ( 39 $rootScope.actualLocation === newLocation && 40 newLocation !== "home" 41 ) { 42 var order = $order.getOrder(); 43 if (order.details.items.length > 0) { 44 $state.go("cart"); 45 } else { 46 $state.go("storeHome"); 47 } 48 } 49 } 50 ); 51 $rootScope.$on("$stateChangeStart", function( 52 e, 53 toState, 54 toParams, 55 fromState, 56 fromParams 57 ) { 58 $profile.isLoggedIn().then(function(res) { 59 var data = res.data.data; 60 // We're setting the extended property here to let the application know that the user who is logged in is an internal employee, 61 // In this case, the user will be presented with additional payment options during checkout. 62 if (!angular.isUndefined(data.extended)) { 63 $order.setExtended(data.extended || false); 64 } 65 }); 66 if ( 67 (!angular.isUndefined($order.getOrder().details.cart_time) && 68 Math.abs(new Date() - new Date($order.getOrder().details.cart_time)) / 69 36e5 > 70 2 71 ) || angular.isUndefined($order.getOrder().details.cart_time)) { 72 $order.clear(); 73 $localStorage.$reset(); 74 } 75 // Due to how the application is rendered through our CMS in some cases the page will be scrolled way down and only the page footer will be visible. 76 // We manually force the window to scroll to the top here to mitigate this issue. 77 $window.scrollTo(0, 0); 78 if (toState.data.requireProfile && toState.name !== "contact") { 79 // We do not need to recollect this information if the user has already provided it to us. 80 if ( 81 angular.isUndefined($order.order.profile.email) && 82 angular.isUndefined($order.order.profile.school_name) 83 ) { 84 e.preventDefault(); 85 $state.go("profile", { nextState: toState.name, params: toParams }); 86 } 87 } 88 89 // activate renewal redirect logic if we have a package url, params haven't been toggled 90 // and profile has been inputted 91 if ( 92 ( toState.name === "package" ) && 93 ( !toParams.validatedForRenewal ) && 94 (Object.keys($order.order.profile).length>0) 95 ) { 96 var productId = toParams.id 97 98 e.preventDefault(); 99 100 $products.getQuestionAnswers($order.getSchool().id) 101 .then(function(resp) { 102 var datesObject = resp.data.data 103 var eligible = false; 104 // today < currExp === true ? expiration date is in the future 105 var today = new Date(new Date) 106 107 // 08/23/2022 108 // https://stackoverflow.com/questions/4310953/invalid-date-in-safari/5646753#5646753 109 // this chunk of logic was breaking on mobile orders, because safari and other mobile browsers were choking on creating this date, returning as "Invalid Date" instead of 110 // the expected datetime. This line of regex works without compromising what is currently working in desktop browsers 111 var currExp = datesObject ? datesObject.oldExpDate.replace(/-/g, "/") : undefined 112 113 114 // lower bound will be 6 months BEFORE expiry 115 var lowerBound = new Date(currExp) || undefined 116 if (lowerBound !== undefined) { lowerBound.setMonth(lowerBound.getMonth()-6) } 117 118 // upper bound will be 9 months AFTER expiry 119 var upperBound = new Date(currExp) || undefined 120 if (upperBound !== undefined) { upperBound.setMonth(upperBound.getMonth()+9) } 121 122 eligible = ( ( today >= lowerBound ) && ( today <= upperBound ) ) ? true : false;
123 124 $products.getMappedInsuranceProduct(productId) 125 .then(function(resp) { 126 127 const currentProductType = resp.data.data.type; 128 const mappedProductId = resp.data.data.mapped_product_id; 129 if ( 130 (eligible && currentProductType==='pkg') || 131 (!eligible && currentProductType==='rnwl') || 132 ( currExp===undefined && currentProductType==='rnwl') 133 ) { 134 // if currentProductType is 'pkg' and eligible for renewal, force renewal 135 // if currentProductType is 'rnwl' and NOT elgible for renewal, force new package 136 // if this is a clean slate order and rnwl was selected, we want to map to a regular package 137 e.preventDefault(); 138 // if we don't specify validatedForRenewal, the 'package' block in the stateProvider will keep getting invoked, 139 // causing an infinite loop 140 $state.go("package", { id: mappedProductId, validatedForRenewal: true }) 141 return; 142 } else { 143 // if currentProductType is 'pkg' and NOT elgible for renewal, do nothing 144 // if currentProductType is 'rnwl' and eligible for renewal, do nothing 145 e.preventDefault(); 146 $state.go("package", { id: productId, validatedForRenewal: true }) 147 return; 148 } 149 }) 150 .catch(function(error) { 151 console.log('promise error on $products.getQuestionAnswers($order.getSchool().id): ', error) 152 }) 153 }) 154 .catch(function(error) { 155 console.log('promise error on $products.getQuestionAnswers($order.getSchool().id): ', error) 156 }) 157 } 158 }); 159 160 // Formly UI.Datepicker related code. 161 var attributes = [ 162 "date-disabled", 163 "custom-class", 164 "show-weeks", 165 "starting-day", 166 "init-date", 167 "min-mode", 168 "max-mode", 169 "format-day", 170 "format-month", 171 "format-year", 172 "format-day-header", 173 "format-day-title", 174 "format-month-title", 175 "year-range", 176 "shortcut-propagation", 177 "datepicker-popup", 178 "show-button-bar", 179 "current-text", 180 "clear-text", 181 "close-text", 182 "close-on-date-selection", 183 "datepicker-append-to-body" 184 ]; 185 186 var bindings = ["datepicker-mode", "min-date", "max-date"]; 187 188 var ngModelAttrs = {}; 189 190 angular.forEach(attributes, function(attr) { 191 ngModelAttrs[camelize(attr)] = { attribute: attr }; 192 }); 193 194 angular.forEach(bindings, function(binding) { 195 ngModelAttrs[camelize(binding)] = { bound: binding }; 196 }); 197 198 formlyConfig.setType({ 199 name: "datepicker", 200 templateUrl: appRoot + "/templates/datepicker.html", 201 wrapper: ["bootstrapLabel", "bootstrapHasError"], 202 defaultOptions: { 203 ngModelAttrs: ngModelAttrs, 204 templateOptions: { 205 datepickerOptions: { 206 format: "MM/dd/yyyy", 207 initDate: new Date().setDate(new Date().getDate() + 1), 208 showWeeks: false, 209 minDate: new Date().setDate(new Date().getDate() + 1) 210 } 211 } 212 }, 213 controller: [
214 "$scope", 215 function($scope) { 216 $scope.datepicker = {}; 217 218 $scope.datepicker.opened = false; 219 220 $scope.datepicker.open = function($event) { 221 $scope.datepicker.opened = !$scope.datepicker.opened; 222 }; 223 } 224 ] 225 }); 226 function camelize(string) { 227 string = string.replace(/[\-_\s]+(.)?/g, function(match, chr) { 228 return chr ? chr.toUpperCase() : ""; 229 }); 230 // Ensure 1st char is always lowercase 231 return string.replace(/^([A-Z])/, function(match, chr) { 232 return chr ? chr.toLowerCase() : ""; 233 }); 234 } 235 });
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.