PageSourceSearch

https://constitutionnet.org/themes/custom/const8/js/theme.js?v=1.03

js constitutionnet.org collected 2026-10-02 02:36:15 UTC 52,306 bytes, 1,552 lines download raw bytes

1var $ = jQuery;
2
3constB3 = new function ($) {  // Private stuff
4
5
6  var self = this,
7
8      /* These breakpoints should correspond to Bootstrap's as defined in variables.less */
9      cssBreakpoints = {
10        xs: 480,
11        sm: 768,
12        md: 992,
13        lg: 1200
14      },
15
16      /* How long after a resize event the resizing should be considered finished and the resize event processed */
17      resizeTriggerDelay = 200,
18
19      /* Array of resize handlers to be executed on (delayed) window resize */
20      resizeHandlers = {},
21
22      /* Array of callback functions to execute when DOM is ready */
23      documentReadyCallbacks = [],
24
25      getParameterByName = function (name, url) {
26        if (!url) {
27          url = window.location.href;
28        }
29        name = name.replace(/[\[\]]/g, "\\$&");
30        var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
31            results = regex.exec(url);
32        if (!results) return null;
33        if (!results[2]) return '';
34        return decodeURIComponent(results[2].replace(/\+/g, " "));
35      },
36
37      /**
38       * Find the max height of any objects in the selector and set all to this height
39       */
40      matchHeights = function ($jq) {
41        "use strict";
42        var maxCssHeight = 0;
43        $jq.each(function () {
44          var thisHeight = $(this).height(); // $(this).css('height').replace('px', '');
45          maxCssHeight = Math.max(maxCssHeight, thisHeight);
46        }).height(maxCssHeight);
47      },
48
49      /**
50       *
51       */
52      initializeResizeListening = function () {
53        $(window).on('resize', function () {
54          var curWidth = document.documentElement.clientWidth;
55          self.waitForFinalEvent(function () {
56            for (var id in resizeHandlers) {
57              if (resizeHandlers.hasOwnProperty(id)) {
58                var resizeHandler = resizeHandlers[id];
59                if (resizeHandler.breakpoints.max > curWidth && resizeHandler.breakpoints.min <= curWidth) {
60                  resizeHandler.callback();
61                  if (resizeHandler.onceOnly) {
62                    self.removeBreakpointListener(id);
63                  }
64                }
65              }
66            }
67          }, resizeTriggerDelay, 'resizeHandlers');
68        }).resize();
69      },
70
71      harmonizeHeights = function () {
72        var $row2 = $('#fp-row-2'),
73            $row3 = $row2.siblings('#fp-row-3'),
74            maxCssHeight = 0,
75            resetHeights = function () {
76              $row2
77                  .find('#row2-cn-news .padder.boxlightgrey, .fp-newsbox-caption')
78                  .css('height', 'auto');
79            },
80            resetHeights2 = function () {
81              $row3.find('.padder.boxlightgrey, .boxbeige')
82                  .css('height', 'auto');
83            };
84        self.addBreakpointListener({min: 'md'}, function () {
85          resetHeights();
86          $row2
87              .find('.news, #row2-cn-news .padder.boxlightgrey')
88              .each(function () {
89                var thisHeight = $(this).height(); // $(this).css('height').replace('px', '');
90                maxCssHeight = Math.max(maxCssHeight, thisHeight);
91              })
92              .filter('.padder.boxlightgrey')
93              .height(maxCssHeight);
94
95          $row2
96              .find('.fp-newsbox-caption')
97              .each(function () {
98                var $this = $(this),
99                    $cropper = $this.siblings('.image-cropper');
100                if ($cropper.length > 0) {
101                  $this.height(maxCssHeight - $cropper.css('height').replace('px', ''));
102                }
103              });
104
105
106        }, 'harmonizeHeights');
107
108        self.addBreakpointListener(null, function () {
109
110          var maxCssHeight = 0;
111          resetHeights2();
112          $row3
113              .find('.news, .boxbeige')
114              .filter(':visible')
115              .each(function () {
116                maxCssHeight = Math.max(maxCssHeight, $(this).css('height').replace('px', ''));
117              })
118              .filter('.boxbeige')
119              .css('height', maxCssHeight);
120
121          $row3
122              .find('.fp-newsbox-caption')
123              .each(function () {
124                var $this = $(this),
125                    $cropper = $this.siblings('.image-cropper');
126                if ($cropper.length > 0) {
127                  $this.css('height', maxCssHeight - $cropper.height() + 'px');
128                }
129              });
130        }, 'harmonizeHeights2');
131
132        self.addBreakpointListener({max: 'md'}, function () {
133          resetHeights();
134        }, 'stopHarmonizeHeights');
135      },
136
137      systemOfGovernmentTables = new function () {
138        /**
139         * Initialize the mobile SoG
140         */
141        this.initialize = function () {
142
143          ///
144          // remove old SoG table and replace with new ones
145          ///
146
147          // the following elements are built in node-country_blurb-body.tpl.php:
148          var $sog_desktop = $('table#sog-desktop');
149          var $sog_mobile = $('div#sog-mobile');
150
151          // move them into the position of the old table and then remove the old
152          $('.constOverview')
153              .after($sog_desktop)
154              .after($sog_mobile)
155              .remove();
156
157          // add the class needed for styling
158          $sog_desktop.addClass('constOverview');
159
160          $('.sog-mobile')
161              .on('click', '.branch h3', function () {
162                $(this)
163                    .toggleClass('expanded')
164                    .closest('.branch')
165                    .find('.actor')
166                    .toggle();
167              })
168              .on('click', '.actor h4', function () {
169                $(this)
170                    .toggleClass('expanded')
171                    .find('i')
172                    .toggleClass('icon-plus-squared-alt icon-minus-squared-alt')
173                    .closest('.actor')
174                    .find('.details')
175                    .toggle();
176              })
177              .on('click', '.details h5', function () {
178                $(this)
179                    .toggleClass('expanded')
180                    .siblings()
181                    .toggle();
182              })
183              .find('.actor h4')
184              .prepend('<i class="icon-plus-squared-alt"></i>');
185        };
186
187      }(self),
188
189      initializeSections = function () {
190        var handleSectionHeadingClick = function () {
191          var $this = $(this),
192              $section = $this.next('.section');
193          $this.toggleClass('expanded');
194          $section.slideToggle($this.hasClass('expanded'));
195        };
196        self.addBreakpointListener({max: 'sm'}, function () {
197          $(document)
198              .off('click', '.sectionHeading', handleSectionHeadingClick)
199              .on('click', '.sectionHeading', handleSectionHeadingClick);
200        }, 'sectionClickHandler_add');
201        self.addBreakpointListener({min: 'sm'}, function () {
202          $(document).off('click', '.sectionHeading', handleSectionHeadingClick);
203        }, 'sectionClickHandler_remove');
204      },
205
206      initializeNewsPanels = function () {
207        var $panels = $('#block-voices .panel, #block-analysis .panel');
208        self.addBreakpointListener({max: 'sm'}, function () {
209          // remove collapse.in thus collapsing the content
210          $panels
211              .find('.panel-collapse')
212              .removeClass('in')
213              .end()
214              .find('.accordion-toggle')
215              .addClass('collapsed');
216          // remove any styles set by matchHeights (below)
217          $panels.attr('style', '');
218        }, 'newsPanelCollapse');
219        self.addBreakpointListener({min: 'sm'}, function () {
220          // add back the .in thus showing the content again for >md
221          $panels
222              .height('auto')
223              .find('.panel-collapse')
224              .addClass('in')
225              .end()
226              .find('.accordion-toggle')
227              .removeClass('collapsed');
228          // also match heights
229
230          matchHeights($panels);
231        }, 'newsPanelCollapseExpand');
232      },
233
234      initializeCountryProfileIntrobox = function () {
235        var $ibDownloads = $('.introBox:first'),
236            $introTable = $ibDownloads.find('table'),
237            $as = $introTable.find('td a.more'),
238            $strongs = $introTable.find('strong'),
239            $a,
240            $strong,
241            label;
242
243        $ibDownloads.addClass('introBox-downloads');
244
245        // remove all styles
246        $introTable
247            .find('table, td, p')
248            .removeAttr('style cellspacing cellpadding width');
249
250        // convert links to icons
251        $as.each(function () {
252          $a = $(this);
253          if ($a.html() == 'Link') {
254            $a.html('<img src="/const8/svg/download.svg">');
255          }
256        });
257
258        // tweak headings
259        $strongs.each(function () {
260          $strong = $(this);
261          label = $strong.html();
262          if (label == 'English') {
263            $strong.html('ENG');
264          } else if (label == 'Arabic') {
265            $strong.html('ARB');
266          }
267        });
268
269        //Move dates into their own column
270        $introTable
271            .find('tr')
272            .first()
273            .prepend('<td></td>')
274            .end()
275            .slice(1) //First row contains the headings
276            .each(function () {
277              var $this = $(this),
278                  $firstCol = $this.children().first(),
279                  $date = $firstCol.find('strong'),
280                  date = $date.text();
281              $date.remove(); // remove the old date
282              $firstCol.find("br").remove(); // removing any leftover BR tags
283              $this.html('<td>' + date + '</td>' + $this.html());
284            });
285
286        //Initialize mobile behavior
287        self.addBreakpointListener({max: 'sm'}, function () {
288          var $rows = $introTable
289                  .find('tr'),
290              $headerRow = $rows
291                  .first(),
292              $headerCells = $headerRow.children('td'),
293              $contentRows = $rows
294                  .slice(1),
295              collapsingCellOffset = 2;
296          $introTable.addClass('mobilified');
297          $headerRow.addClass('hidden-xs');
298          $contentRows.each(function () {
299            var $this = $(this),
300                $collapsedContents = $('<div/>', {
301                  'class': 'collapsedCells visible-xs',
302                  html: '<div class="button icon-dot-3"></div><div class="contents"></div>'
303                }),
304                $collapsedContentsContentArea = $collapsedContents
305                    .find('.contents'),
306                $cells = $this
307                    .children('td'),
308                $collectingCell = $cells
309                    .eq(1),
310                $collapsingCells = $cells
311                    .slice(2);
312            $collapsingCells
313                .each(function (idx) {
314                  var $this = $(this),
315                      thisHtml;
316                  $this
317                      .find('br')
318                      .remove();
319                  thisHtml = $.trim($this.find('p').html()).replace(/&nbsp;/g, '');
320                  if (thisHtml.length > 0) {
321                    $collapsedContentsContentArea
322                        .append('<div>' + thisHtml +
323                            $.trim($headerCells.eq(collapsingCellOffset + idx)
324                                .text()) + '</div>');
325                  }
326                })
327                .addClass('hidden-xs');
328            $collectingCell.prepend($collapsedContents);
329          });
330        }, 'convertDTMobile', true);
331
332
333        /* Add mobile specific listeners outside the breakpoint listener above so we don't have to unbind on expand */
334        $introTable.on('click', '.collapsedCells .button', function (e) {
335          var $this = $(this),
336              $parent = $this.parent();
337          if ($introTable.hasClass('mobilified')) {
338            $introTable
339                .find('.expanded')
340                .not($parent)
341                .removeClass('expanded');
342            $parent
343                .toggleClass('expanded');
344            e.stopPropagation();
345          }
346        });
347
348        $('body').on('click', function () {
349          if ($introTable.hasClass('mobilified')) {
350            $introTable
351                .find('.expanded')
352                .removeClass('expanded');
353          }
354        });
355      },
356
357      initializeCountryProfileDocIndex = function () {
358        var $introBoxes = $('body.node-type-country-blurb .introBox');
359        $introBoxes.each(function () {
360          var $ib = $(this);
361          if ($ib.text().match(/Documents Index/)) {
362            $ib.addClass('introBox-docIndex');
363          }
364        });
365      },
366
367      initializeCountryProfileTimeline = function () {
368        var $h2s = $('body.node-type-country-blurb h2');
369        $h2s.each(function () {
370          var $h2 = $(this);
371          if ($h2.text().match(/Timeline/)) {
372            var $timelineTable = $h2.next('table');
373            $timelineTable.addClass('timeline');
374            $timelineTable.removeAttr('width height');
375          }
376        });
377      },
378
379      initializeUnderContentCommentForm = function () {
380        var $form = $('#comment-form');
381        setTimeout(function () {
382          $form
383              .find('#wysiwyg-toggle-edit-comment')
384              .click()
385              .remove();
386        }, 2000);
387      },
388
389      initNewsScrollLoading = function () {
390        var $window = $(window),
391            delay = 300, //Time to wait after final scroll event before triggering
392            proximityLimit = 200, //Distance in pixels from very bottom before triggering
393            $button = $('#loadMoreNews');
394        $button.hide();
395        $window.scroll(function () {
396          self.waitForFinalEvent(function () {
397            if ($window.scrollTop() + document.documentElement.clientHeight + proximityLimit >= document.documentElement.scrollHeight) {
398              $button.click();
399            }
400          }, delay, 'newsScroll');
401        });
402      },
403
404      initVoicesScrollLoading = function () {
405        var $window = $(window),
406            delay = 300, //Time to wait after final scroll event before triggering
407            proximityLimit = 200, //Distance in pixels from very bottom before triggering
408            $button = $('.pager-next a').first(),
409            $filters = $('#views-exposed-form-voices-page-1'),
410            $languageSelect = $filters.find('select[name=language]'),
411            $regionSelect = $filters.find('select[name=region]'),
412            loadUrl;
413
414        if ($button.length == 1) { //Otherwise there are no more results to load
415          loadUrl = $button.attr('href').replace(/\?.*$/, '');
416          $button
417              .data('nextIndex', 1)
418              .closest('.item-list')
419              .hide();
420
421          $window.scroll(function () {
422            self.waitForFinalEvent(function () {
423              var $contentArea = $('#content-area').find('.view-content');
424              if (!$contentArea.hasClass('loading')) {
425                if ($window.scrollTop() +
426                    document.documentElement.clientHeight +
427                    proximityLimit >= document.documentElement.scrollHeight) {
428                  $contentArea.addClass('loading');
429                  $.ajax({
430                    url: loadUrl,
431                    data: {
432                      page: $button.data('nextIndex'),
433                      contentonly: 1,
434                      language: $languageSelect.val(),
435                      region: $regionSelect.val()
436                    },
437                    success: function (data) {
438                      var $newArticles = $(data).find('#content-area .view-content .views-row');
439                      $newArticles.appendTo($contentArea);
440                      $button.data('nextIndex', $button.data('nextIndex') + 1);
441                      $contentArea.removeClass('loading');
442                    }
443                  });
444                }
445              }
446            }, delay, 'newsScroll');
447          });
448        }
449      },
450
451      fixLogoProportions = function () {
452        var $ideaLogo = $('#logo-idea');
453        self.addBreakpointListener(null, function () {
454          $ideaLogo
455              .height($ideaLogo.width());
456        }, 'logoProportions')
457      },
458
459
460      initGlossary = function ($body) {
461        "use strict";
462        //Working fiddle at http://jsfiddle.net/y53mG/3/
463        if ($body.hasClass('path-glossary')) {
464          var letterMap = [];
465          var letters = [];
466          // prepare a new letter bar which uses the translated order
467          var $letterBar = $('<div class="glossary-links">' +
468              '<a class="glossary-item" id="glossaryAll" href="#" style="text-transform:none;">All</a></div>');
469          var curLetter = 'All';
470
471          $('.glossary-list').find('dt').each(function () {
472            "use strict";
473            var me = $(this);
474            var textLower = me.text().toLowerCase();
475            // remove stuff in brackets
476            textLower = textLower.replace(/\(.*?\)/, '').trim();
477            // remove al- prefix
478            textLower = textLower.replace(/^\u0627\u0644/, '').trim();
479            // get the first letter
480            var firstChar = textLower.charAt(0);
481            // skip the first char if it's an alef
482            if (firstChar == '\u0627') firstChar = textLower.charAt(1);
483            // normalize alef ( إ and ​أ)
484            if (firstChar == '\u0622' || firstChar == '\u0623' || firstChar == '\u0625') firstChar = '\u0627';
485            // normalize waw
486            if (firstChar == '\u0624') firstChar = '\u0648';
487            // normalize yeh
488            if (firstChar == '\u0626') firstChar = '\u064a';
489            // map objects into letter
490            if (!letterMap[firstChar]) {
491              // make sure we have a place to record the items for this letter
492              letterMap[firstChar] = [];
493              letters.push(firstChar);
494            }
495            letterMap[firstChar].push(me.next('dd').andSelf());
496          });
497          letters;
498          // output the new navbar in order
499          for (var i = 0; i < letters.length; i++) {
500            // &#8203; is a zero-width space
501            $letterBar.append('|&#8203;<a href="#" class="glossary-item active">' + letters[i].toUpperCase() + '</a>');
502          }
503          $letterBar.append($('.glossary-alphabar-instructions'));
504
505          var $glossary_links = $('.glossary-links');
506          $glossary_links.remove(); //Remove the old bar
507          $letterBar.insertBefore('dl'); // insert the new one
508
509          $('#glossPromptCustom').insertBefore('dl').show();
510
511          $('#glossaryAll').click(function () {
512            if (curLetter != 'All') {
513              glossaryToggleAll(letterMap);
514              curLetter = 'All';
515            }
516            else {
517              glossaryToggleAll(letterMap, true);
518              curLetter = null;
519            }
520            return false;
521          });
522
523          $('a.glossary-item.active').click(function () {
524            "use strict";
525            var me = $(this);
526            var clickedLetter = me.text().toLowerCase();
527            if (curLetter) {
528              if (curLetter == 'All') {
529                glossaryToggleAll(letterMap, true);
530              }
531              else {
532                for (var j = 0; j < letterMap[curLetter].length; j++) {
533                  letterMap[curLetter][j].hide();
534                }
535              }
536            }
537            curLetter = clickedLetter;
538            for (var k = 0; k < letterMap[curLetter].length; k++) {
539              letterMap[curLetter][k].show();
540            }
541            return false;
542          });
543        }
544      },
545
546      initFaqSections = function () {
547        var $faq = $('.faq');
548        // start with answers hidden
549        $faq.find('div.faq-dt-hide-answer').removeClass("faq-qa-visible");
550        $faq.find('div.faq-dd-hide-answer').addClass("collapsible collapsed");
551        // intialize click events
552        $faq
553            .on('click', '.faq-qa-header', function () {
554              var $this = $(this);
555              if (getDocumentWidth() < cssBreakpoints.sm) {
556                $this
557                    .toggleClass('expanded')
558                    .next('.faq-qa')
559                    .slideToggle();
560              }
561            })
562            .on('click', '.faq-question', function () {
563              var $this = $(this);
564              $this
565                  .toggleClass('faq-qa-visible')
566                  .next('.faq-answer')
567                  .slideToggle();
568              return false;
569            });
570      },
571
572      glossaryToggleAll = function (letterMap, hide) {
573        "use strict";
574        var func = hide ? 'hide' : 'show';
575        for (var letter in letterMap) {
576          if (letterMap.hasOwnProperty(letter)) {
577            var entry = letterMap[letter];
578            for (var i = 0; i < entry.length; i++) {
579              entry[i][func]();
580            }
581          }
582        }
583      },
584
585      getDocumentWidth = function () {
586        return document.documentElement.clientWidth;
587      }
588
589      ;
590
591  //Public stuff
592
593  /**
594   * Compares current document width with the defined breakpoints and returns the smalles mode name that
595   * matches the current width.
596   *
597   */
598  this.getWidthBand = function () {
599    var curWidth = getDocumentWidth(),
600        band = 'xxs';
601    for (var mode in cssBreakpoints) {
602      if (cssBreakpoints.hasOwnProperty(mode)) {
603        if (curWidth < cssBreakpoints[mode]) {
604          break;
605        }
606        band = mode;
607      }
608    }
609    return band;
610  };
611
612  /**
613   *
614   * @param breakpoints (optional) object with min and/or max properties identifying at which widths the callback should be invoked (default: no width restrictions)
615   * @param callback The function to execute on resize
616   * @param id A unique identifier allowing for keeping track of the handler and for allowing the removal of it
617   * @param onceOnly (optional) boolean that indicates whether the handler should be invoked only once (default: false)
618   */
619  this.addBreakpointListener = function (breakpoints, callback, id, onceOnly) {
620
621    breakpoints = breakpoints || {};
622
623    breakpoints.max = breakpoints.max || 99999;
624    breakpoints.min = breakpoints.min || -1;
625
626    if (isNaN(parseFloat(breakpoints.max)) || !isFinite(breakpoints.max)) {
627      breakpoints.max = cssBreakpoints[breakpoints.max];
628    }
629
630    if (isNaN(parseFloat(breakpoints.min)) || !isFinite(breakpoints.min)) {
631      breakpoints.min = cssBreakpoints[breakpoints.min];
632    }
633
634    if (!(breakpoints.max && breakpoints.min)) {
635      console.error('Invalid breakpoints received');
636      return;
637    }
638
639    resizeHandlers[id] = {
640      callback: callback,
641      breakpoints: breakpoints,
642      onceOnly: !!onceOnly
643    };
644  };
645
646  /**
647   * Removes a previously registered breakpoint listener
648   *
649   * @param id the unique identifier used when registering the listener
650   */
651  this.removeBreakpointListener = function (id) {
652    delete resizeHandlers[id];
653  };
654
655  this.registerDocumentReadyCallback = function (callback) {
656    documentReadyCallbacks.push(callback);
657  };
658
659  /**
660   * Self-executing function that results in a function that can be used for delaying execution of a callback
661   * function for events that happen many times in quick succession. When invoked, the callback is scheduled
662   * for execution after a custom delay, and if invoked again before that time has passed, the pending execution
663   * is cancelled and a new one is scheduled.
664   */
665  this.waitForFinalEvent = function () {
666    var registry = {};
667    /**
668     * @param callback - The callback function the execution of which should be delayed
669     * @param timeout - The time in ms that needs to pass after an invocation before the callback is executed
670     * @param id - A unique identifier, to make calls for different events/callbacks not conflict
671     */
672    return function (callback, timeout, id, fireIntermediate) {
673      var forcedRun = false,
674          now;
675      if (fireIntermediate) {
676        now = Date.now();
677      }
678      id = id || 'Default';
679      if (registry[id]) {
680        clearTimeout(registry[id].timeout);
681        if (fireIntermediate && now > registry[id].lastRun + timeout) {
682          callback();
683          forcedRun = true;
684          registry[id].lastRun = now;
685        }
686      }
687      else {
688        registry[id] = {
689          timeout: null,
690          lastRun: 0
691        }
692      }
693      if (!forcedRun) {
694        registry[id].timeout = setTimeout(function () {
695          if (fireIntermediate) {
696            registry[id].lastRun = Date.now();
697          }
698          callback();
699        }, timeout);
700      }
701    };
702  }();
703
704  this.collapseSelectLabels = function ($selects, parentSelector) {
705    $selects.each(function () {
706      var $this = $(this),
707          $myLabel = $this
708              .closest(parentSelector)
709              .find('label');
710      $this
711          .find('option:first')
712          .text($myLabel.text());
713      $myLabel.hide();
714    });
715  };
716
717  this.uncollapseSelectLabels = function ($selects, parentSelector) {
718    $selects.each(function () {
719      var $this = $(this),
720          $myLabel = $this
721              .closest(parentSelector)
722              .find('label');
723      $this
724          .find('option:first')
725          .text('- All -');
726
727      $myLabel.show();
728    });
729  };
730
731  /**
732   * Adjusts the size (and matches line-height) of headings and trims down teaser length when the text and image heights are very different.
733   * This makes the front page look more balanced.
734   */
735  this.balanceImageText = function ($box, repeatsLeft) {
736    repeatsLeft = repeatsLeft !== undefined ? repeatsLeft : 3; // maximum 3 iterations
737    if (repeatsLeft <= 0) return; // avoid infinite loop
738    // how high is the image right now?
739    var imgHeight = $box.find('#news-photo-container img').height();
740    var txtHeight = $box.find('div.news').height();
741    var $teaser = $box.find(".teaser");
742    var $h2 = $box.find("h2");
743    var h2_size = parseInt($h2.css('font-size')); // in pixels
744    var longText = $teaser.data('complete-text');
745    var diffHeight = imgHeight - txtHeight;
746    var unitSize = 30;
747    var diffUnits = Math.ceil(Math.abs(diffHeight) / unitSize);
748    var didSomething = false;
749    if (diffHeight > unitSize) {
750      // we should make the text longer
751      $teaser.html(longText);
752      $teaser.css('line-height', 1.5 + (diffHeight / 500));
753      $teaser.data('length-visible', longText.length);
754      if (h2_size < 25) {
755        // make heading bigger
756        h2_size += diffUnits;
757        $h2.css('font-size', (h2_size + diffUnits ) + "px");
758        $h2.css('line-height', (h2_size * 1.3) + "px");
759        didSomething = true;
760      } else {
761        // extra line height
762        $h2.css('line-height', (h2_size * 1.4) + "px");
763      }
764    } else if (diffHeight < 0) { // since the image comes right to the edge, the text should not even be a pixel longer
765      var lengthHeading = $h2.html().length;
766      var currLength = $teaser.data('length-visible') || (180 - lengthHeading);
767      var lengthVisible = Math.max(80, 0.85 * currLength); // make it shorter than now (but never shorter than 80)
768      if (longText.length > lengthVisible + 10 && lengthVisible < currLength) {
769        $teaser.html(longText.substr(0, lengthVisible) + '&hellip;');
770        didSomething = true;
771      }
772      $teaser.css('line-height', 1.5 + (diffHeight / 500));
773      $teaser.data('length-visible', lengthVisible); // update the length
774      var h2_min = 20; // never smaller than this
775      if (h2_size > h2_min) {
776        // we've already cut the teaser, let's make the heading smaller too
777        h2_size = Math.max(h2_min, h2_size - diffUnits);
778        $h2.css('font-size', h2_size + "px");
779        $h2.css('line-height', (h2_size * 1.3) + "px");
780        didSomething = true;
781      }
782    }
783    if (didSomething) {
784      repeatsLeft -= 1;
785      this.balanceImageText($box, repeatsLeft); // iterate again
786    }
787  };
788
789  //Immediate initializations
790
791
792  //Initializations made once DOM is ready
793
794  $(document).ready(function () {
795    var countryFirst = $('#country-detail-body').find('p').first();
796    var relatedNews = $('#related-country-news');
797    $(relatedNews).insertAfter(countryFirst).css('display', 'block');
798    $("<hr />").insertAfter(relatedNews);
799
800
801    var $body = $('body'),
802        $collapseSelects;
803    initializeResizeListening(); //Might put unnecessary load on pages that don't need this
804    // initializeSections(); //Should perhaps only be run on country profile pages
805    initializeCountryProfileDocIndex();
806    initializeCountryProfileTimeline();
807    initializeUnderContentCommentForm();
808    fixLogoProportions();
809    initGlossary($body);
810
811    // Support for conditional comments has been removed in Internet Explorer 10 and gt..
812    var ms_ie = false;
813    var ua = window.navigator.userAgent;
814    var old_ie = ua.indexOf('MSIE ');
815    var new_ie = ua.indexOf('Trident/');
816    if ((old_ie > -1) || (new_ie > -1)) {
817      ms_ie = true;
818    }
819    if (ms_ie) {
820      $body.addClass('ie');
821    }
822
823    //Page specific ones
824
825    $('.fp-videos').each(function(){
826      var vidUrl = $(this).data('url');
827      var vidUrlConvert = vidUrl.replace('watch?v=', 'embed/');
828      // console.log(vidUrl);
829      // console.log(vidUrlConvert);
830
831      $(this).html('<iframe width="560" height="315" src="' + vidUrlConvert + '" frameborder="0" allowfullscreen></iframe>');
832    });
833
834    var fp = $body.hasClass('front');
835
836    if (fp) {
837      // it's the front page
838      harmonizeHeights();
839      var $box = $('#fp-news').find('div.row a.box');
840      // try and make the primary news item and image pretty
841      self.addBreakpointListener({min: 'sm'}, function () {
842        constB3.balanceImageText($box);
843      }, 'primaryNews');
844      // constB3.balanceImageText($box); // run once now
845    }
846
847    if ($body.hasClass('path-news')) {
848      initNewsScrollLoading();
849      initializeNewsPanels();
850
851      $collapseSelects = $('#block-cn-21')
852          .find('form.blue')
853          .find('select');
854
855      self.addBreakpointListener({max: 'sm'}, function () {
856        constB3.collapseSelectLabels($collapseSelects, '.form-group');
857      }, 'collapseNewsSelects');
858
859      self.addBreakpointListener({min: 'sm'}, function () {
860        constB3.uncollapseSelectLabels($collapseSelects, '.form-group');
861      }, 'uncollapseNewsSelects');
862    }
863
864    if ($body.hasClass('path-news-voices')) {
865      initVoicesScrollLoading()
866    }
867
868    if ($body.hasClass('path-analysis')) {
869      initNewsScrollLoading();
870
871      var $lang_form_select = $('#views-exposed-form-analysis-page-1').find('select');
872      if ($lang_form_select && $lang_form_select.val() == 'All') {
873        var urlLang = getParameterByName('language');
874        if (!urlLang) {
875          // form set to default of "all" - we'll change to the current language instead
876          $lang_form_select.val(window.langId);
877        }
878      }
879
880      // Arabic page? (No longer existant)
881      var $exposed_form_analysis = $('#views-exposed-form-analysis-page-2');
882      $exposed_form_analysis
883          .find('select')
884          .children('option:first-child')
885          .text('- All -');
886      $collapseSelects = $exposed_form_analysis
887          .find('select');
888
889      self.addBreakpointListener({max: 'sm'}, function () {
890        constB3.collapseSelectLabels($collapseSelects, '.views-exposed-widget');
891      }, 'collapseAnalysisSelects');
892
893      self.addBreakpointListener({min: 'sm'}, function () {
894        constB3.uncollapseSelectLabels($collapseSelects, '.views-exposed-widget');
895      }, 'uncollapseAnalysisSelects');
896    }
897
898    if ($body.hasClass('path-search-node')) {
899      // it's the Drupal search page
900      if (window.location.hash == '#advanced') {
901        // we should expand out the advanced search options immediately
902        $('form.search-form fieldset.search-advanced.collapsible').removeClass('collapsed');
903      }
904    }
905
906    if ($body.hasClass('path-about') || $body.hasClass('path-constitutions-faq')) {
907      initFaqSections();
908    }
909
910    var $rowTitle = $('#row-title');
911    // format the page heading to match the content type
912    var $contentArea = $('#content-area');
913    var $contentRow = $contentArea.find('> .content > .row:first');
914    var $preTitle = $rowTitle.find('div.pre');
915
916    var $commentWrapper = $contentArea.find('> .comment-wrapper');
917    $contentArea.find('> .content > .row > .inner').append($commentWrapper);
918
919
920    if ($contentRow.length == 1) {
921      var $columns = $contentRow.children('div');
922      if ($columns.length == 2) {
923        // this page has two content sections
924        $preTitle.addClass($columns[0].className);
925        $rowTitle.find('div:last-child').attr('class', $columns[1].className); // set the class attribute
926      }
927    }
928
929    if ($body.hasClass('node-type-country-blurb')) {
930      systemOfGovernmentTables.initialize();
931      initializeCountryProfileIntrobox();
932      // copy flag up into the heading
933      $('.country-details img.flag').clone().appendTo($preTitle);
934      // override the default hiding for the title
935      $preTitle.removeClass('hidden-xs').addClass('col-xs-3 col-sm-2');
936      $preTitle.find('img.flag').addClass('hidden-md hidden-lg');
937      $rowTitle.find('div:last-child').removeClass('col-lg-12 col-xs-12').addClass('col-xs-9 col-sm-10');
938    }
939
940    $('[data-toggle="offcanvas"]').click(function () {
941      $('.row-offcanvas').toggleClass('active')
942    });
943
944    for (var i = 0; i < documentReadyCallbacks.length; i++) {
945      documentReadyCallbacks[i]();
946    }
947
948    // Add target=_blank to external links
949    $('a[href^="//"], a[href^="http"]')
950        .not('[href*="' + window.location.hostname + '"]')
951        .attr('target', '_blank');
952  });
953  function windowPopup(url, width, height) {
954  // Calculate the position of the popup so
955  // it’s centered on the screen.
956  var left = (screen.width / 2) - (width / 2),
957      top = (screen.height / 2) - (height / 2);
958
959    window.open(
960      url,
961      "",
962      "menubar=no,toolbar=no,resizable=yes,scrollbars=yes,width=" 
962+ width + ",height=" + height + ",top=" + top + ",left=" + left
963    );
964  }
965
966  $(".js-social-share").on("click", function (e) {
967    e.preventDefault();
968    console.log('hi')
969
970    windowPopup($(this).attr("href"), 500, 300);
971  });
972
973
974  $("#testimonialModal").on("show.bs.modal", function (event) {
975    var button = $(event.relatedTarget);
976    var modal = $(this);
977    modal
978      .find(".modal-tes-flag")
979      .html('<div class="content" style="background-image: url(' + button.data("flag") + ')"></div>');
980    modal.find(".modal-tes-country").text(button.data("country"));
981    modal.find(".modal-description").html(button.data("description"));
982    modal.find(".modal-tes-name").text(button.data("name"));
983    modal
984      .find(".modal-tes-youtube")
985      .html(
986        '<iframe width="560" height="315" src="https://www.youtube.com/embed/' +
987          button.data("youtube") +
988          '" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>'
989      );
990  });
991
992  //close modal remove video from playing
993  $("#testimonialModal").on("hidden.bs.modal", function (event) {
994    $("#testimonialModal iframe").attr("src", $("#testimonialModal iframe").attr("src"));
995  });
996
997
998
999  $('a[href*="#"]')
1000    // Remove links that don't actually link to anything
1001    .not('[href="#"]')
1002    .not('[href="#0"]')
1003    .click(function (event) {
1004      // On-page links
1005      if (
1006        location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') &&
1007        location.hostname == this.hostname
1008      ) {
1009        // Figure out element to scroll to
1010        var target = $(this.hash);
1011        target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
1012        // Does a scroll target exist?
1013        if (target.length) {
1014          // Only prevent default if animation is actually gonna happen
1015          event.preventDefault();
1016          $('html, body').animate({
1017            scrollTop: target.offset().top
1018          }, 1000, function () {
1019            // Callback after animation
1020            // Must change focus!
1021            var $target = $(target);
1022            $target.focus();
1023            if ($target.is(":focus")) { // Checking if the target was focused
1024              return false;
1025            } else {
1026              $target.attr('tabindex', '-1'); // Adding tabindex for elements not focusable
1027              $target.focus(); // Set focus again
1028            };
1029          });
1030        }
1031      }
1032    });
1033
1034
1035    $('.myanmarpubimage').mouseover(function() {
1036      const id = $(this).data('mmpubid');
1037      $('.fauxhover-' + id).mouseover();
1038    });
1039
1040    $('.myanmarpubimage').mouseleave(function() {
1041      const id = $(this).data('mmpubid');
1042      $(".fauxhover-" + id).mouseleave();
1043    });
1044
1045
1046  const ttWidth = 24; // Tips width
1047  const tbWidth = 800; // Tips box width
1048  const tbWHalf = tbWidth / 2; // Half of tips box width
1049  const pointyOffset = 26;
1050
1051function mmtooltip()  {
1052  $('.mtooltip').mouseover(function () {
1053    const tipsX = $(this).offset().left + (ttWidth / 2);
1054    $(this).find('.pointy').remove();
1055    // reset
1056    $(this).find('.mtoolbox').removeClass('top bottom');
1057
1058    const vw = $(window).width(); // Viewport width
1059    // Checking left spacing
1060    if (tipsX > (tbWHalf)) {
1061      $(this).find('.mtoolbox').css('transform', 'translateX(-' + (tbWHalf) + 'px)');
1062
1063      // Check right spacing
1064      if (tipsX + (tbWHalf) > vw) {
1065        $(this).find('.mtoolbox').css('transform', 'translateX(-' + (tbWHalf + ((tipsX + tbWHalf + 80 ) - vw)) + 'px)');
1066      }
1067    } else {
1068      $(this).find('.mtoolbox').css('transform', 'translateX(-' + tipsX + 'px)'); }$(this).addClass('active');
1069
1070    // Defauly tooltip box is on top
1071    $(this).find('.mtoolbox').addClass('top');
1072    // var pointyTranslateY = "translateY(50%)";​
1073    var pointyTranslateY = 'translateY(50%)';
1074    // console.log($(this).find('.mtoolbox').offset().top);
1075
1076   if ($(this).find('.mtoolbox').offset().top <= $(document).scrollTop()) {
1077      $(this).find('.mtoolbox').removeClass('top');
1078      $(this).find('.mtoolbox').addClass('bottom');
1079      pointyTranslateY = 'translateY(-50%)';
1080    }
1081    const tbLeft = $(this).find('.mtoolbox').offset().left; // Tips box left position on viewport
1082
1083    // Append pointy
1084    $(this).find('.mtoolbox').find('.tooltip-content').append('<div class="pointy"></div>');
1085
1086    // Position pointy
1087    $(this).find('.mtoolbox').find('.pointy').css('transform', 'translateX('+ (tipsX - tbLeft - pointyOffset) + 'px) ' + pointyTranslateY);
1088  });
1089
1090  $('.mtooltip').on('mouseout', function () {
1091    $(this).removeClass('active');
1092  });
1093
1094}
1095
1096
1097mmtooltip();
1098
1099}(jQuery);
1100
1101/** Add back jQuery.browser removed in jQuery 1.9 */
1102// Limit scope pollution from any deprecated API
1103(function () {
1104
1105  var matched, browser;
1106
1107// Use of jQuery.browser is frowned upon.
1108// More details: http://api.jquery.com/jQuery.browser
1109// jQuery.uaMatch maintained for back-compat
1110  jQuery.uaMatch = function (ua) {
1111    ua = ua.toLowerCase();
1112
1113    var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
1114        /(webkit)[ \/]([\w.]+)/.exec(ua) ||
1115        /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
1116        /(msie) ([\w.]+)/.exec(ua) ||
1117        ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
1118        [];
1119
1120    return {
1121      browser: match[1] || "",
1122      version: match[2] || "0"
1123    };
1124  };
1125
1126  matched = jQuery.uaMatch(navigator.userAgent);
1127  browser = {};
1128
1129  if (matched.browser) {
1130    browser[matched.browser] = true;
1131    browser.version = matched.version;
1132  }
1133
1134// Chrome is Webkit, but Webkit is also Safari.
1135  if (browser.chrome) {
1136    browser.webkit = true;
1137  } else if (browser.webkit) {
1138    browser.safari = true;
1139  }
1140
1141  jQuery.browser = browser;
1142})();
1143
1144/**
1145 *
1146 * @param $container {jQuery} A DIV or FORM which contains inputs
1147 */
1148function const8_label2placeholder($container) {
1149  $container.find('input[type=text], input[type=email], input[type=password], textarea, select').each(function () {
1150    var $self = $(this);
1151    var $label = $container.find("label[for='" + $self.attr("id") + "']");
1152    var textOrig = $label.text();
1153    var textClean = textOrig.replace(new RegExp(":.*$"), ""); // replace colon and any "required" SPAN etc.
1154    if (textClean) {
1155      if ($self.prop("tagName").toLowerCase() == 'select') {
1156        $self.prepend('<option value="" disabled="true">- ' + textClean + '</option>').val('');
1157      } else {
1158        // it's an input or textarea
1159        $self.attr('placeholder', textClean);
1160        if (textOrig.indexOf('*') > 0) $self.attr('required', true);
1161      }
1162      $label.hide();
1163    }
1164  });
1165}
1166
1167/**
1168 * Move the comments form if present
1169 */
1170$(document).ready(function () {
1171
1172  // find the placeholder for the slidein
1173  var $commentsFloater = $('#comments-floater');
1174
1175  // look for the container
1176  var $boxComments = $('.box-comments');
1177  // now look for the bottom form (the original which we will soon clone)
1178  var $commentForm = $boxComments.find('.comment-form');
1179
1180  var skip = true;
1181
1182  // if ($commentForm.length < 1) { // Origianal code
1183  if (skip) {
1184    // no comments for this page
1185    // remove the placeholder
1186    $commentsFloater.remove();
1187  } else { // we've found the comments section
1188    // replace labels with placeholder attributes (apply to both the bottom and slidein versions)
1189
1190    const8_label2placeholder($boxComments);
1191
1192    // copy the new comment form into that
1193    $commentsFloater.find("> .content").html($commentForm.clone());
1194
1195    var $h2 = $commentsFloater.find("h2");
1196    var widthComments = 355; // make it less wide
1197
1198    // now that we've measured, add the .vert class to rotate
1199    $h2 = $commentsFloater.find("h2.vert"); // update selector so that we don't accidentally touch any H2 appended below
1200
1201    // hide labels
1202    $commentsFloater.find("#edit-name-1").attr('placeholder', $commentsFloater.find("#edit-name-1").attr('value'));
1203    $commentsFloater.find("#edit-name-1").attr('value', '');
1204    $commentsFloater.find("#edit-mail-1").attr('placeholder', $("#edit-mail").attr('placeholder'));
1205    $commentsFloater.find("#edit-comment-1").attr('placeholder', $("#edit-comment").attr('placeholder'));
1206    $commentsFloater.find("label").hide();
1207    $commentsFloater.find("fieldset").hide();
1208    $commentsFloater.find(".description").hide();
1209    $commentsFloater.find(".form-textarea").css({
1210      visibility: 'visible',
1211      display: 'block'
1212    });
1213
1214    // captcha
1215    $commentsFloater.find(".captcha").before('<div class="captcha-switch"/>');
1216    $commentsFloater.find(".captcha").remove(); // broken container
1217
1218    // everything is OK, show the floater
1219    $commentsFloater.show();
1220
1221    // mouseover will slide out the form, but do nothing if it's already out
1222    $h2.mouseover(function () {
1223      var $captchaSwitch = $commentsFloater.find(".captcha-switch");
1224      if ($captchaSwitch.length && !$captchaSwitch.html().length) {
1225        $boxComments.find(".captcha").clone().appendTo($captchaSwitch);
1226      }
1227
1228      var slide_status = $h2.data('slide-status');
1229      if (slide_status) {
1230        // it's already out so do nothing
1231      } else {
1232        // it's hidden
1233        $commentsFloater.animate({left: 0});
1234        $h2.data('slide-status', !slide_status);
1235      }
1236    });
1237
1238    // click will slide in or out depending
1239    $h2.click(function () {
1240      var $captchaSwitch = $commentsFloater.find(".captcha-switch");
1241      if ($captchaSwitch.length && !$captchaSwitch.html().length) {
1242        $boxComments.find(".captcha").clone().appendTo($captchaSwitch);
1243      }
1244
1245      var slide_status = $h2.data('slide-status');
1246      if (slide_status) {
1247        // it's already out
1248        $commentsFloater.animate({left: "-" + widthComments});
1249      } else {
1250        // it's hidden
1251        $commentsFloater.animate({left: 0});
1252      }
1253      $h2.data('slide-status', !slide_status);
1254    });
1255
1256    // now tweak the bottom form
1257    $commentForm.find('fieldset').hide(); // hide the input form fieldset
1258  }
1259
1260  // match the padding-top of aside to the height of the H1
1261  $('aside #padder-right').css('padding-top', $('#row-title').css('height'));
1262
1263  // login form
1264  const8_label2placeholder($('#user-login'));
1265  // register form
1266  const8_label2placeholder($('#user-register'));
1267  // subscirbe
1268  const8_label2placeholder($('#simplenews-subscription-manager-form'));
1269
1270  // make views exposed forms auto submit on change
1271  var $form_exposted = $('.views-exposed-form');
1272  $form_exposted.find('.views-submit-button').hide();
1273  $form_exposted.find('.views-exposed-widget select').attr('onchange', 'form.submit();');
1274
1275
1276  $('input[type=file]')
1277      .wrap('<div class="btn btn-default btn-file"></div>')
1278      .before('Choose file...');
1279
1280  var $body_first = $('body:first');
1281  if ($body_first.hasClass('path-photographs')) {
1282    var $form_gallery = $('#views-exposed-form-photo-galleries-page-1');
1283    $form_gallery.find('#edit-actions').hide();
1284    $form_gallery
1285        .find('#edit-category')
1286        .bind('change', function () {
1287          $form_gallery.submit();
1288        });
1289  }
1290
1291  // console.log($body_first.hasClass('path-primers'));
1292  if ($body_first.hasClass('path-primers')) {
1293    var $form_lib = $('#views-exposed-form-idea-library-page-2');
1294    $form_lib.find('#edit-actions').hide();
1295    $form_lib
1296        .find('#edit-issues-target-id')
1297        .bind('change', function () {
1298          $form_lib.submit();
1299        });
1300  }
1301
1302  /**
1303   * Community register form
1304   */
1305  var scrollUserRegisterForm = function () {
1306    $(".user-register-indicator").hide();
1307    var hash = 'user-register-anchor';
1308    var top = parseInt($('#' + hash).offset().top);
1309    $('html, body').animate({
1310      scrollTop: top
1311    }, 1000);
1312    return false;
1313  };
1314
1315  $(".user-register-indicator").click(function () {
1316    $(".user-register-wrapper").toggle('slow', scrollUserRegisterForm);
1317  });
1318
1319  $(".user-register-scroll").click(function () {
1320    $(".user-register-wrapper").toggle('slow', scrollUserRegisterForm);
1321  });
1322
1323  var $contentAnalysis = $('body.path-analysis .view-analysis');
1324
1325  if ($contentAnalysis.length) {
1326    if ($contentAnalysis.find(".pager-next").length) {
1327      $contentAnalysis.attr('data-url', $contentAnalysis.find(".pager-next").children("a").attr('href'));
1328    }
1329    $contentAnalysis.find(".item-list").hide();
1330  }
1331
1332});
1333
1334/* Add firebug logging functionality to jQuery objects. Safe for non-console environments. */
1335jQuery.fn.log = function (msg) {
1336  $.log("%s: %o", msg, this); // calls jQuery.log below
1337  return this;
1338};
1339
1340/* Add firebug logging functionality as a "static" method on the jQuery object. Safe for non-console environments. */
1341jQuery.log = function (msg) {
1342  if (window.console && window.console.log) {
1343    console.log(msg); // uncomment this to show logging again
1344  }
1345  else if ((window.location.search + window.location.hash).indexOf('ptest') > -1) {
1346    var $body = $('body');
1347    if ($body.find('#specialLogArea').length == 0) {
1348      $body.append('<div id="specialLogArea"></div>');
1349    }
1350    var logArea = $('#specialLogArea');
1351    logArea.html(logArea.html() + '<br />' + msg);
1352  }
1353};
1354
1355$(document).ready(function () {
1356  var $content = $('body.path-analysis .view-analysis');
1357
1358
1359  if ($content.length) {
1360    if ($content.find(".pager-next").length) {
1361      $content.attr('data-url', $content.find(".pager-next").children("a").attr('href'));
1362    }
1363    $content.find(".item-list").hide();
1364  }
1365
1366  $('html').removeClass('no-js');
1367  $('[data-toggle=offcanvas]').click(function () {
1368    $('.row-offcanvas').toggleClass('active');
1369  });
1370
1371
1372  var $searchTypes = $('.view-case-laws .search-types');
1373  if ($searchTypes.length) {
1374    $searchTypes.find('a').each(function () {
1375      "use strict";
1376      var $searchType = $(this);
1377      if (window.location.pathname.match(new RegExp($searchType.attr('href') + '$'))) {
1378        $searchType.addClass('current');
1379      }
1380    });
1381  }
1382
1383
1384  var externalLink = $('.ex-tab');
1385  if (externalLink) {
1386    // console.log('booya')
1387
1388    // $('.extab').css("background", 'green');
1389    $('.ex-tab:first-child .exstory').prop("checked", true);
1390  }
1391
1392  var myanmarmenu = $('.menu--myconstitution-myanmar');
1393  if (myanmarmenu) {
1394    // console.log('sdf', myanmarmobilemenu)
1395    myanmarmenu.clone().appendTo('#myanmarmobilemenu')
1396    // $('#myanmarmobilemenu').html('lksdjf')
1397
1398  }
1399
1400  var myanmarmenumm = $('.menu--myconstitution-myanmar-mm');
1401  if (myanmarmenumm) {
1402    // console.log('sdf', myanmarmobilemenu)
1403    myanmarmenumm.clone().appendTo('#myanmarmobilemenu')
1404    // $('#myanmarmobilemenu').html('lksdjf')
1405
1406  }
1407
1408  $('.exstory-accordion li').click(function(){
1409    $(this).toggleClass(' active ');
1410    $(this).siblings().removeClass(' active ');
1411    $('.exstory-content').stop().slideUp();
1412    $('.active .exstory-content').stop().slideDown();
1413    return false;
1414  });
1415
1416  $('.exstory-accordion li:first-child').addClass('active');
1417  $('.exstory-accordion li:first-child .exstory-content').stop().slideDown();
1418
1419  $('.node-type-myanmar-multimedia .region-bottom').addClass('container-padd');
1420
1421  var getUrlParameter = function getUrlParameter(sParam) {
1422    var sPageURL = window.location.search.substring(1),
1423        sURLVariables = sPageURL.split('&'),
1424        sParameterName,
1425        i;
1426
1427    for (i = 0; i < sURLVariables.length; i++) {
1428        sParameterName = sURLVariables[i].split('=');
1429
1430        if (sParameterName[0] === sParam) {
1431            return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
1432        }
1433    }
1434    return false;
1435  };
1436  
1437  // Documents page language filter handler
1438  if ($('#documents-language-filter').length > 0) {
1439    const button = $('#documents-language-filter-apply');
1440    const langSselect = $('#documents-language-select');
1441
1442    const langParam = getUrlParameter('lang');
1443    if (langParam) {
1444      langSselect.val(langParam);
1445      langSselect.trigger('change');
1446    }
1447
1448    button.on('click', function(){
1449      const lang = langSselect.val();
1450      const baseUrl = window.location.href.split('&lang=')[0];
1451
1452      if (lang !== '') {
1453        window.location = baseUrl + '&lang=' + lang;
1454      }
1455    });
1456  }
1457
1458
1459
1460  if ($('.cn-readmore--content').length > 0) {
1461    $('.cn-readmore--content').each(function () {
1462      const id = $(this).attr('id');
1463      console.log('id', id);
1464      const summary = $(this).find('.cn-readmore--summary');
1465      if (summary.find('p').length > 0) {
1466        console.log('A');
1467        summary.find('p').last().append('&nbsp;<a href="#" class="cn-readmore--click" data-target="#' + id + '">Read more</a>')
1468      } else {
1469        console.log('B');
1470        summary.append('&nbsp;<a href="#" class="cn-readmore--click" data-target="#' + id + '">Read more</a>')
1471      }
1472
1473      const body = $(this).find('.cn-readmore--full');
1474      body.append('</br><a href="#" class="cn-readless--click" data-target="#' + id + '" style="display: xnone;">Read less</a>');
1475    })
1476
1477
1478    $('.cn-readmore--click').on('click', function(e){
1479      e.preventDefault();
1480
1481      const target = $($(this).data('target'));
1482      const oh = target.outerHeight();
1483      const id = target.attr('id');
1484      
1485      target.css('height', oh+'px');
1486      target.css('overflow', 'hidden');
1487
1488      target.find('.cn-readmore--summary').hide();
1489      target.find('.cn-readmore--full').show();
1490
1491      const nh = target.find('.cn-readmore--full').outerHeight();
1492
1493      setTimeout(() => {
1494        target.css('height', nh+'px');
1495      }, 10);
1496
1497      setTimeout(() => {
1498        target.css('height', 'auto');
1499      }, 300);
1500    });
1501
1502    $('.cn-readless--click').on('click', function(e){
1503      e.preventDefault();
1504
1505      const target = $($(this).data('target'));
1506      const oh = target.outerHeight();
1507      target.css('height', oh+'px');
1508      
1509      target.find('.cn-readmore--summary').show();
1510      const sh = target.find('.cn-readmore--summary').outerHeight(); // Summary height
1511      target.find('.cn-readmore--summary').hide();
1512
1513      setTimeout(() => {
1514        target.css('height', sh+'px');
1515      }, 10);
1516
1517      setTimeout(() => {
1518        target.find('.cn-readmore--summary').show();
1519        target.find('.cn-readmore--full').hide();
1520        target.css('height', 'auto');
1521      }, 300);
1522    });
1523  }
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552});

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.