PageSourceSearch

https://plancaldwell.com/Scripts/ScriptLoader.js

js plancaldwell.com collected 2026-10-08 22:55:58 UTC 26,477 bytes, 874 lines download raw bytes

1var loadedScripts = {
2  agendaComments: {
3    script: "/Scripts/AgendaComments.js"
4  },
5  alphabeticalSortModule: {
6    script: "/Scripts/AlphabeticalSortModule.js"
7  },
8  analytics: {
9    script: "https://www.google-analytics.com/analytics.js"
10  },
11  budgetQuestion: {
12    script: "/Scripts/budgetQuestion.js"
13  },
14  fundingAllocator: {
15    script: "/Scripts/FundingAllocator/FundingAllocator.js"
16  },
17  qaTool: {
18    script: "/dist/qa-tool.bundle.js"
19  },
20  bootstrap: {
21    script: "/Scripts/bootstrap.min.js"
22  },
23  bootstrap5: {
24    script:
25      "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
26  },
27  BootstrapToast: {
28    script: "/Scripts/BootstrapToast.js"
29  },
30  CalendarEmbed: {
31    script: "/Scripts/CalendarEmbed.js"
32  },
33  constants: {
34    script: "/Scripts/constants.js"
35  },
36  commentMap: {
37    script: "/Scripts/commentMap.js"
38  },
39  ckEditor4: {
40    // AB#9952 / WASP#756: customers with ModuleSettings.DisableCkEditor never receive the
41    // CKEditor bundle. CkEditorPlainText.js exposes the same CKEDITOR surface over plain
42    // inputs, so no caller changes. Deliberately a GETTER rather than a value computed at
43    // load time: it resolves on every read, so this file has no ordering dependency on when
44    // the page sets window.piDisableCkEditor.
45    get script() {
46      return window.piDisableCkEditor === true
47        ? "/Scripts/CkEditorPlainText.js"
48        : "/Scripts/CkEditor4/ckeditor.js";
49    },
50    // The loader assigns `loaded` on this object; a get-only `script` would throw on an
51    // accidental write in strict mode, so absorb one harmlessly.
52    set script(ignored) {}
53  },
54  canvg: {
55    script: "/Scripts/charts/canvg.min.js"
56  },
57  stackedCards: {
58    script: "/Scripts/stackedCards.js"
59  },
60  commentBuilder: {
61    script: "/Scripts/CommentBuilder.js"
62  },
63  commentSection: {
64    script: "/Scripts/CommentSection.js"
65  },
66  consensus: {
67    script: "/Scripts/consensus-module.js"
68  },
69  esri: {
70    script: "https://js.arcgis.com/4.23/"
71  },
72  fullCalendar: {
73    script:
74      "https://cdn.jsdelivr.net/npm/[email protected]/index.global.min.js"
75  },
76  fullCalendarModule: {
77    script: "/Scripts/FullCalendarModule.js"
78  },
79  mapCommentTools: {
80    script: "/Scripts/MapCommentTools.js"
81  },
82  myData: {
83    script: "/Scripts/MyData/my-data.js"
84  },
85  myDataModuleLoader: {
86    script: "/Scripts/MyData/my-data.module-loader.js"
87  },
88  myDataPortalView: {
89    script: "/Scripts/MyData/my-data.portal-view.js"
90  },
91  myDataSearchUI: {
92    script: "/Scripts/MyData/my-data.search-ui.js"
93  },
94  myDataSectionUI: {
95    script: "/Scripts/MyData/my-data.section-ui.js"
96  },
97  canvasToBlob: {
98    script:
99      "https://blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js"
100  },
101  engagementMapBase: {
102    script: "/Scripts/engagementMap/base.js"
103  },
104  esriMapsHub: {
105    script: "/Scripts/engagementMap/hubMap.js"
106  },
107  canvasToImage: {
108    script: "https://superal.github.io/canvas2image/canvas2image.js"
109  },
110  chosen: {
111    script: "/lib/chosen/chosen.jquery.min.js"
112  },
113  chatBot: {
114    script: "/Scripts/chat-widget.js"
115  },
116  chartDataLoader: {
117    script: "/Scripts/charts/chart-data-loader.js"
118  },
119  chartFactory: {
120    script: "/Scripts/charts/chart-factory.js"
121  },
122  contactForm: {
123    script: "/Scripts/ContactForm/ContactForm.js"
124  },
125  customStyleEditor: {
126    script: "/Scripts/CustomStyleEditor.js"
127  },
128  customReport: {
129    script: "/Scripts/Reporting/custom-report.js"
130  },
131  customRegistrationForm: {
132    script: "/Scripts/CustomRegistrationForm.js"
133  },
134  dataTables: {
135    script: "/Scripts/dataTables/jquery.dataTables.min.js"
136  },
137  dropzone: {
138    script: "/Scripts/dropzone.js"
139  },
140  datepicker: {
141    script:
142      "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"
143  },
144  dateTimePicker: {
145    script: "/lib/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js"
146  },
147  demographicModule: {
148    script: "/Scripts/demographicModule.js"
149  },
150  dynamicSignupBuilder: {
151    script: "/Scripts/AdminShared/DynamicSignupBuilder.js?v=bs5-2"
152  },
153  emailCommunicationUI: {
154    script: "/Scripts/AdminShared/EmailCommunicationUI.js?v=bs5-2"
155  },
156  draftEmail: {
157    script: "/Scripts/AdminShared/DraftEmail.js"
158  },
159  emailProject: {
160    script: "/Scripts/AdminShared/EmailProject.js"
161  },
162  flotMin: {
163    script: "/Scripts/charts/flot/jquery.flot.min.js"
164  },
165  flotTooltip: {
166    script: "/Scripts/charts/flot/jquery.flot.tooltip.min.js"
167  },
168  flotTime: {
169    script: "/Scripts/charts/flot/jquery.flot.time.js"
170  },
171  // AB#10165: pinned to 3.64 because DrawingManager was removed in 3.65
172  // (deprecated Aug 2025). 3.64 is the newest version that still ships it.
173  // Google keeps only ~4 numbered versions live, so this pin stops resolving
174  // around mid-Feb 2027 -- and it expires SILENTLY: an unavailable v= is served
175  // the latest version, not an error. Supersedes the v=quarterly pin from
176  // Bug 8928, which broke when quarterly rolled to 3.65 in Aug 2026.
177  // Permanent fix (migrate off DrawingManager) tracked separately.
178  googleMaps: {
179    // AB#10257: v=quarterly is a rolling channel. It rolled onto 3.65, which removed
180    // DrawingManager, and constructing one threw before mappoll.js could finish init -
181    // taking the whole interactive map question down, not just line drawing. Pinned
182    // below 3.65 until we migrate off DrawingManager. Google retires old versions, so
183    // this is a stopgap with an expiry, not a resting place.
184    script:
185      "https://maps.googleapis.com/maps/api/js?key=AIzaSyAiRD1TL9mZQfmpBOZ3MaX_pGxI5MlLCZI&loading=async&v=3.64&libraries=places,drawing&callback=initScriptLoaderMapCallback"
186  },
187  googleMapsMarkerClusterer: {
188    script: "https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"
189  },
190  highlight: {
191    script: "/Scripts/AdminShared/Jquery.Highlight.js"
192  },
193  html2Canvas: {
194    script: "/lib/html2canvas/html2canvas.min.js"
195  },
196  ideaBoard: {
197    script: "/Scripts/ideaBoard.js"
198  },
199  imagePollShape: {
200    script: "/Scripts/imagePollShape.js"
201  },
202  intercomHelper: {
203    script: "/Scripts/intercom-helper.js"
204  },
205  isotope: {
206    script: "https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"
207  },
208  jqueryUIWidget: {
209    script: "/Scripts/file-upload/jquery.ui.widget.js"
210  },
211  jqueryFileUpload: {
212    script: "/lib/blueimp-file-upload/js/jquery.fileupload.min.js"
213  },
214  jqueryIframeTransport: {
215    script: "/lib/blueimp-file-upload/js/jquery.iframe-transport.min.js"
216  },
217  jqueryCloudinary: {
218    script: "/Scripts/file-upload/jquery.cloudinary.js"
219  },
220  loadImageAll: {
221    script: "/Scripts/file-upload/load-image.all.min.js"
222  },
223  jqueryFileUploadProcess: {
224    script: "/Scripts/file-upload/jquery.fileupload-process.js"
225  },
226  jqueryFileUploadImage: {
227    script: "/Scripts/file-upload/jquery.fileupload-image.js"
228  },
229  jqueryFileUploadUI: {
230    script: "/Scripts/file-upload/jquery.fileupload-ui.js"
231  },
232  jqueryUi: {
233    script: "/lib/jqueryui/jquery-ui.min.js?v=1.13.3"
234  },
235  linkify: {
236    script: "/Scripts/linkify.min.js"
237  },
238  linkifyJquery: {
239    script: "/Scripts/linkify-jquery.min.js"
240  },
241  locationPoll: {
242    script: "/Scripts/locationpoll.js"
243  },
244  mapPoll: {
245    // ?v= bumped with each participant-facing fix (AB#9710 add-point tray,
246    // AB#10879 duplicate-pin recovery) so returning participants are not served a
247    // cached copy of the broken script (same pattern as matrix).
248    script: "/Scripts/mappoll.js?v=10879"
249  },
250  mapPollParcel: {
251    script: "/Scripts/mappoll.parcels.js"
252  },
253  mapPollShape: {
254    script: "/Scripts/mapPollShape.js"
255  },
256  polygonCentering: {
257    script: "/Scripts/polygonCentering.js"
258  },
259  mapLabel: {
260    script: "/Scripts/maplabel-compiled.js"
261  },
262  mapA11y: {
263    script: "/Scripts/AdminShared/map-a11y.js"
264  },
265  mapA11yStatus: {
266    script: "/Scripts/AdminShared/map-a11y-status.js"
267  },
268  mapLayerManager: {
269    script: "/Scripts/MapLayerManager.js"
270  },
271  mapPollEditor: {
272    script: "/Scripts/mappolleditor.js"
273  },
274  masonry: {
275    script: "https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"
276  },
277  magnificPopup: {
278    script: "/lib/magnific-popup.js/jquery.magnific-popup.min.js"
279  },
280  materialExtensions: {
281    script: "/Scripts/materialExtensions.js"
282  },
283  matrix: {
284    script: "/Scripts/poll.matrix.js?v=a6321"
285  },
286  meetingTranscriptionsUI: {
287    script: "/Scripts/MeetingTranscriptionsUI.js"
288  },
289  moment: {
290    script: "/lib/moment.js/moment.min.js"
291  },
292  mustache: {
293    script: "/Scripts/mustache.min.js"
294  },
295  newPoll: {
296    script: "/Scripts/new-poll.js"
297  },
298  notify: {
299    script: "/Scripts/notify1.min.js"
300  },
301  noUiSliderJquery: {
302    script: "/Scripts/jquery.nouislider.js"
303  },
304  noUiSlider: {
305    script:
306      "https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/11.0.3/nouislider.min.js"
307  },
308  offlineEventUI: {
309    script: "/Scripts/OfflineEventUI.js"
310  },
311  signalRCoreBridge: {
312    script: "/dist/signalRCoreBridge.bundle.js"
313  },
314  poll: {
315    script: "/Scripts/poll.js"
316  },
317  pollSlider: {
318    script: "/Scripts/poll_slider.js"
319  },
320  pollVisioner: {
321    script: "/Scripts/poll.visioner.js"
322  },
323  projectsOnMapViewer: {
324    script: "/Scripts/projectsOnMapViewer.js"
325  },
326  projectPage: {
327    script: "/Scripts/Project/ProjectPageUI.js"
328  },
329  parsley: {
330    script: "/Scripts/parsley.min.js"
331  },
332  ranking: {
333    script: "/Scripts/RankPoll.js"
334  },
335  rgbcolor: {
336    script: "/Scripts/charts/rgbcolor.js"
337  },
338  starModule: {
339    script: "/Scripts/poll.starModule.js"
340  },
341  tools: {
342    script: "/Scripts/Tools.js"
343  },
344  twitterBootstrapWizard: {
345    script: "/lib/twitter-bootstrap-wizard/jquery.bootstrap.wizard.min.js"
346  },
347  zoomDesktop: {
348    script: "/Scripts/zoom.js"
349  },
350  d3: {
351    script: "/Scripts/Bubble/D3-old.js"
352  },
353  entityCloud: {
354    script: "/Scripts/Bubble/entity-cloud.js"
355  },
356  organizationEditor: {
357    script: "/Scripts/AdminShared/OrganizationEditor.js"
358  },
359  organizationListUI: {
360    script: "/Scripts/AdminShared/OrganizationListUI.js"
361  },
362  organizationMap: {
363    script: "/Scripts/AdminShared/OrganizationMap.js"
364  },
365  audienceShared: {
366    script: "/Scripts/AdminShared/AudienceShared.js"
367  },
368  googleAutoComplete: {
369    script: "/Scripts/GoogleAutoComplete.js"
370  }
371};
372
373// AB#9726: `ckEditor` used to be the CKEditor 4.4.7 build under /CkEditor/.
374// There is now a single CKEditor 4 build in the application, so `ckEditor` is an
375// alias for `ckEditor4` -- the SAME object, not a copy, so both share one
376// `loaded` flag. Two separate entries would trigger a redundant fetch and a full
377// re-parse of a ~1.3 MB build on any page that uses both. The build does guard
378// against re-initialising (`if (window.CKEDITOR && window.CKEDITOR.dom) return;`),
379// so this is about not paying for work that is thrown away, not correctness.
380loadedScripts.ckEditor = loadedScripts.ckEditor4;
381
382var ScriptLoader = {
383  /**
384   * Loads a set of scripts and executes callbacks once all scripts are loaded.
385   *
386   * @param {Object} scriptSet - An object containing scripts and callbacks.
387   * @param {Function} callback - Function to be called once all scripts are loaded.
388   */
389  loadScriptArray: function (scriptSet, callback, extraConfig = null) {
390    var allScriptsLoaded = true;
391    scriptSet.callbacks = scriptSet.callbacks || [];
392    if (callback) {
393      scriptSet.callbacks.push(callback);
394    }
395    $.each(scriptSet.scripts, function (index, value) {
396      if (value.loaded === false || value.loaded == null) {
397        allScriptsLoaded = false;
398        var script = document.createElement("script");
399        script.src = value.script;
400        if (extraConfig && extraConfig.type) {
401          script.type = extraConfig.type;
402        }
403        var oldOnload = script.onload;
404        script.onload = script.onreadystatechange = function () {
405          if (!this.readyState || this.readyState === "complete") {
406            scriptSet.scripts[index].loaded = true;
407            ScriptLoader.loadScriptArray(scriptSet);
408            oldOnload && oldOnload();
409          }
410        };
411
412        var oldOnerror = script.onerror;
413        script.onerror = function () {
414          // A 404 returns the /Error HTML page (text/html), which fires onerror, not
415          // onload. Mark this script done so one failed load can't stall the whole chain.
416          if (window.console && console.error) {
417            console.error(
418              "ScriptLoader: failed to load script " + value.script
419            );
420          }
421          scriptSet.scripts[index].loaded = true;
422          ScriptLoader.loadScriptArray(scriptSet);
423          oldOnerror && oldOnerror();
424        };
425
426        var head =
427          document.head || document.getElementsByTagName("head")[0] || document;
428        head.appendChild(script);
429        scriptSet.scripts[index].loaded = "pending";
430        if (!scriptSet.async) {
431          return false;
432        }
433      } else if (value.loaded === "pending") {
434        allScriptsLoaded = false;
435        if ($ != null) {
436          var $script = $("script[src='" + value.script + "']");
437          if ($script.length) {
438            var pendingScript = $script[0];
439            var pendingOnload = pendingScript.onload;
440            pendingScript.onload = function () {
441              scriptSet.scripts[index].loaded = true;
442              ScriptLoader.loadScriptArray(scriptSet);
443              pendingOnload && pendingOnload();
444            };
445          }
446        }
447        if (!scriptSet.async) {
448          return false;
449        }
450      }
451    });
452    if (allScriptsLoaded && scriptSet.callbacks.length) {
453      scriptSet.callbacks.forEach(function (cb, index) {
454        scriptSet.callbacks[index] = null; // prevent loop
455        cb && cb();
456      });
457      scriptSet.callbacks = [];
458    } else {
459      return false;
460    }
461  },
462  isScriptLoadedOnPage: function (scriptUrl) {
463    return document.querySelector('script[src="' + scriptUrl + '"]') !== null;
464  },
465  scriptArrays: {
466    agendaComments: {
467      scripts: [
468        loadedScripts.constants,
469        loadedScripts.agendaComments,
470        loadedScripts.commentBuilder,
471        loadedScripts.tools,
472        loadedScripts.moment
473      ],
474      async: true
475    },
476    alphabeticalSortModule: {
477      scripts: [loadedScripts.alphabeticalSortModule],
478      async: true
479    },
480    chosen: { scripts: [loadedScripts.chosen] },
481    ckEditor: { scripts: [loadedScripts.ckEditor] },
482    ckEditor4: { scripts: [loadedScripts.ckEditor4] },
483    consensus: {
484      scripts: [
485        loadedScripts.consensus,
486        loadedScripts.materialExtensions,
487        loadedScripts.tools,
488        loadedScripts.stackedCards
489      ],
490      async: true
491    },
492    calendarEmbed: {
493      scripts: [loadedScripts.calendarEmbed],
494      async: true
495    },
496    customReportCore: {
497      scripts: [
498        loadedScripts.customReport,
499        loadedScripts.chartFactory,
500        loadedScripts.chartDataLoader
501      ],
502      async: true
503    },
504    dateTimePicker: {
505      scripts: [
506        loadedScripts.moment,
507        loadedScripts.tools,
508        loadedScripts.dateTimePicker
509      ],
510      async: false
511    },
512    dropzone: { scripts: [loadedScripts.dropzone] },
513    bootstrap: { scripts: [loadedScripts.bootstrap] },
514    flot: {
515      scripts: [
516        loadedScripts.flotMin,
517        loadedScripts.flotTooltip,
518        loadedScripts.flotTime
519      ]
520    },
521    bootstrapToast: { scripts: [loadedScripts.BootstrapToast] },
522    fullCalendar: {
523      scripts: [loadedScripts.fullCalendarModule, loadedScripts.fullCalendar],
524      async: true
525    },
526    googleAutoComplete: {
527      scripts: [loadedScripts.googleAutoComplete, loadedScripts.maps],
528      async: true
529    },
530    mapShapeScripts: {
531      scripts: [
532        loadedScripts.constants,
533        loadedScripts.googleMaps,
534        loadedScripts.polygonCentering,
535        loadedScripts.mapLabel,
536        loadedScripts.mapA11yStatus,
537        loadedScripts.mapPollShape
538      ],
539      async: false
540    },
541    ideaBoard: {
542      scripts: [
543        loadedScripts.constants,
544        loadedScripts.commentSection,
545        loadedScripts.ideaBoard,
546        loadedScripts.isotope,
547        loadedScripts.tools
548      ],
549      async: false
550    },
551    pollVisioner: {
552      scripts: [
553        loadedScripts.constants,
554        loadedScripts.commentSection,
555        loadedScripts.pollVisioner,
556        loadedScripts.tools
557      ],
558      async: false
559    },
560    imageShapeScripts: {
561      scripts: [
562        loadedScripts.constants,
563        loadedScripts.polygonCentering,
564        loadedScripts.imagePollShape
565      ],
566      async: false
567    },
568    locationPollScripts: {
569      scripts: [
570        loadedScripts.constants,
571        loadedScripts.googleMaps,
572        loadedScripts.mapA11yStatus,
573        loadedScripts.locationPoll
574      ],
575      async: false
576    },
577    mapPollScripts: {
578      scripts: [
579        loadedScripts.constants,
580        loadedScripts.googleMaps,
581        loadedScripts.mapCommentTools,
582        loadedScripts.mapA11yStatus,
583        loadedScripts.mapPoll
584      ],
585      async: false
586    },
587    mapPollParcelScripts: {
588      scripts: [
589        loadedScripts.constants,
590        loadedScripts.googleMaps,
591        loadedScripts.mapCommentTools,
592        loadedScripts.mapA11yStatus,
593        loadedScripts.mapPoll,
594        loadedScripts.mapPollParcel,
595        loadedScripts.parsley
596      ],
597      async: true
598    },
599    mapComments: {
600      scripts: [
601        loadedScripts.constants,
602        loadedScripts.googleMaps,
603        loadedScripts.commentMap
604      ],
605      async: false
606    },
607    maps: {
608      scripts: [
609        loadedScripts.googleMapsMarkerClusterer,
610        loadedScripts.googleMaps,
611        loadedScripts.mapLayerManager,
612        // AB#9979: every consumer of this array names its map region via window.piMapA11y, so the
613        // helper ships with the map libraries rather than being wired 
613into each host page.
614        loadedScripts.mapA11y
615      ]
616    },
617    mapsMarkerClusterer: {
618      scripts: [loadedScripts.googleMapsMarkerClusterer]
619    },
620    myData: {
621      scripts: [
622        loadedScripts.esri,
623        loadedScripts.myData,
624        loadedScripts.myDataPortalView,
625        loadedScripts.myDataSectionUI,
626        loadedScripts.myDataModuleLoader,
627        loadedScripts.myDataSearchUI,
628        loadedScripts.googleMaps
629      ],
630      async: false
631    },
632    rankPollScripts: {
633      scripts: [
634        loadedScripts.constants,
635        // AB#9727: was a separate `sorting` entry pointing at a CDN copy of jQuery UI. Now that
636        // both resolve to the same vendored file, they must share one entry -- loadScriptArray
637        // dedupes on the entry's own `loaded` flag, not on the URL, so two entries with the same
638        // src would append and execute jQuery UI twice on any page that pulled both.
639        loadedScripts.jqueryUi,
640        loadedScripts.ranking
641      ],
642      async: false
643    },
644    chatBotScripts: { scripts: [loadedScripts.chatBot], async: false },
645    intercomHelper: {
646      scripts: [loadedScripts.tools, loadedScripts.intercomHelper]
647    },
648    magnificPopup: { scripts: [loadedScripts.magnificPopup], async: false },
649    matrix: {
650      scripts: [loadedScripts.matrix, loadedScripts.constants],
651      async: true
652    },
653    matrixStar: {
654      scripts: [
655        loadedScripts.matrix,
656        loadedScripts.starModule,
657        loadedScripts.constants
658      ],
659      async: true
660    },
661    audienceShared: {
662      scripts: [loadedScripts.esri, loadedScripts.audienceShared],
663      async: true
664    },
665    engagementMapBase: {
666      scripts: [loadedScripts.esri, loadedScripts.engagementMapBase],
667      async: true
668    },
669    esriMapsHub: {
670      scripts: [
671        loadedScripts.mustache,
672        loadedScripts.esri,
673        loadedScripts.esriMapsHub
674      ],
675      async: false
676    },
677    newPoll: { scripts: [loadedScripts.newPoll], async: true },
678    projectPage: {
679      scripts: [
680        loadedScripts.constants,
681        loadedScripts.projectPage,
682        loadedScripts.tools
683      ]
684    },
685    notify: { scripts: [loadedScripts.notify] },
686    zoomDesktop: { scripts: [loadedScripts.zoomDesktop], async: false },
687    linkify: {
688      scripts: [loadedScripts.linkify, loadedScripts.linkifyJquery],
689      async: false
690    },
691    contactForm: {
692      scripts: [
693        loadedScripts.constants,
694        loadedScripts.parsley,
695        loadedScripts.contactForm
696      ],
697      async: true
698    },
699    offlineEvent: {
700      scripts: [
701        loadedScripts.constants,
702        loadedScripts.signalRCoreBridge,
703        loadedScripts.offlineEventUI,
704        loadedScripts.tools,
705        loadedScripts.parsley,
706        loadedScripts.chosen
707      ],
708      async: true
709    },
710    organizationEditor: {
711      scripts: [
712        loadedScripts.organizationEditor,
713        loadedScripts.mapLayerManager
714      ],
715      async: true
716    },
717    organizationListUI: {
718      scripts: [loadedScripts.organizationListUI],
719      async: true
720    },
721    organizationMap: {
722      scripts: [loadedScripts.esri, loadedScripts.organizationMap],
723      async: true
724    },
725    commentSection: {
726      scripts: [
727        loadedScripts.constants,
728        loadedScripts.mustache,
729        loadedScripts.tools,
730        loadedScripts.commentSection,
731        loadedScripts.constants
732      ],
733      async: false
734    },
735    highlight: { scripts: [loadedScripts.highlight] },
736    fileUpload: {
737      scripts: [loadedScripts.jqueryUIWidget, loadedScripts.jqueryFileUpload]
738    },
739    imageUpload: {
740      scripts: [
741        loadedScripts.jqueryUIWidget,
742        loadedScripts.loadImageAll,
743        loadedScripts.canvasToBlob,
744        loadedScripts.jqueryIframeTransport,
745        loadedScripts.jqueryFileUpload,
746        loadedScripts.jqueryFileUploadProcess,
747        loadedScripts.jqueryFileUploadImage,
748        loadedScripts.jqueryCloudinary
749      ],
750      async: false
751    },
752    demographicModule: {
753      scripts: [
754        loadedScripts.constants,
755        loadedScripts.demographicModule,
756        loadedScripts.twitterBootstrapWizard,
757        loadedScripts.parsley,
758        loadedScripts.chosen,
759        loadedScripts.jqueryUi
760      ],
761      async: true
762    },
763    budgetQuestion: {
764      scripts: [
765        loadedScripts.constants,
766        loadedScripts.budgetQuestion,
767        loadedScripts.notify
768      ],
769      async: false
770    },
771    communityQa: {
772      scripts: [loadedScripts.qaTool]
773    },
774    fundingAllocator: {
775      scripts: [
776        loadedScripts.constants,
777        loadedScripts.noUiSlider,
778        loadedScripts.noUiSliderJquery,
779        loadedScripts.fundingAllocator
780      ],
781      async: false
782    },
783    parsley: { scripts: [loadedScripts.parsley], async: false },
784    projectsOnMapPublic: {
785      scripts: [
786        loadedScripts.googleMaps,
787        loadedScripts.constants,
788        loadedScripts.polygonCentering,
789        loadedScripts.mapLabel,
790        loadedScripts.mapA11yStatus,
791        loadedScripts.projectsOnMapViewer,
792        loadedScripts.chosen
793      ]
794    },
795    saveToImage: {
796      scripts: [
797        loadedScripts.rgbcolor,
798        loadedScripts.canvg,
799        loadedScripts.html2Canvas,
800        loadedScripts.canvasToImage
801      ],
802      async: true
803    },
804    slider: {
805      scripts: [
806        loadedScripts.constants,
807        loadedScripts.noUiSlider,
808        loadedScripts.noUiSliderJquery,
809        loadedScripts.pollSlider
810      ],
811      async: true
812    },
813    tools: { scripts: [loadedScripts.tools] },
814    dataTables: { scripts: [loadedScripts.dataTables] },
815    entityCloud: { scripts: [loadedScripts.d3, loadedScripts.entityCloud] },
816    meetingTranscriptionsUI: {
817      scripts: [loadedScripts.meetingTranscriptionsUI]
818    },
819    customRegistrationForm: { scripts: [loadedScripts.customRegistrationForm] },
820    datepicker: {
821      scripts: [
822        loadedScripts.moment,
823        loadedScripts.tools,
824        loadedScripts.datepicker
825      ],
826      async: false
827    }
828  },
829  loadNew: function (scriptPathArray, async, callback) {
830    var newEntry = { scripts: [], async: async };
831    $.each(scriptPathArray, function (idx, path) {
832      newEntry.scripts.push({ script: path });
833    });
834    ScriptLoader.loadScriptArray(newEntry, callback);
835  },
836  waitForGoogle: function () {
837    return new Promise((res) => {
838      const waitForGoogle = setInterval(() => {
839        if (window.isGoogleLoaded) {
840          clearInterval(waitForGoogle);
841          return res();
842        }
843      }, 500);
844    });
845  }
846};
847
848window.initScriptLoaderAdminScripts && window.initScriptLoaderAdminScripts();
849window.isGoogleLoaded = false;
850
851function initScriptLoaderMapCallback() {
852  // this is an empty method required by Google Maps js to prevent console errors
853  window.isGoogleLoaded = true;
854
855  // AB#10165: the v=3.64 pin above expires silently -- when 3.64 falls out of
856  // Google's supported window (~mid-Feb 2027) they serve the latest version
857  // instead of erroring, and every drawing tool dies with no obvious cause.
858  // Feature detection cannot catch this: in 3.65+ google.maps.drawing still
859  // exists and DrawingManager is still a function -- it is just inert. The
860  // resolved version string is the only reliable signal.
861  if (
862    window.google &&
863    google.maps &&
864    google.maps.version &&
865    google.maps.version.indexOf("3.64.") !== 0
866  ) {
867    console.error(
868      "Google Maps resolved to " +
869        google.maps.version +
870        " but the map drawing tools require 3.64.x -- the v=3.64 pin has expired. " +
871        "Drawing (Regions, Audiences, project maps, map polls) will silently stop working. See AB#10165."
872    );
873  }
874}

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.