{{ $js := .Site.Data.lib.js }}
{{ $css := .Site.Data.lib.css }}

{{ $jquery := resources.Get "js/jquery.min.js" | resources.Fingerprint }}
<script defer src="{{ $jquery.RelPermalink }}"></script>
{{ $clipboard := resources.Get "js/clipboard.min.js" | resources.Fingerprint }}
<script defer src="{{ $clipboard.RelPermalink }}"></script>
{{ $enquire := resources.Get "js/enquire.min.js" | resources.Fingerprint }}
<script defer src="{{ $enquire.RelPermalink }}"></script>
{{ $zzo := resources.Get "js/zzo.js" | resources.Minify | resources.Fingerprint }}
<script defer src="{{ $zzo.RelPermalink }}"></script>

{{ if $.Param "enablePhotoSwipe" }}
  {{ $photoSwipe := resources.Get `js/photoswipe.min.js` | resources.Fingerprint }}
  <script defer src="{{ $photoSwipe.RelPermalink }}"></script>
  {{ $photoSwipeUi := resources.Get `js/photoswipe-ui-default.min.js` | resources.Fingerprint }}
  <script defer src="{{ $photoSwipeUi.RelPermalink }}"></script>
  {{ $photoSwipeStyle := resources.Get "css/photoswipe/photoswipe.css" | resources.Minify }}
  <link rel="stylesheet" href="{{ $photoSwipeStyle.RelPermalink }}">
  {{ $photoSwipeSkin := resources.Get "css/photoswipe/custom-skin.css" | resources.Minify }}
  <link rel="stylesheet" href="{{ $photoSwipeSkin.RelPermalink }}">
{{ end }}

{{ if $.Param "enableToc" }}
  {{ $toc := resources.Get "js/jquery.toc.min.js" | resources.Fingerprint }}
  <script defer src="{{ $toc.RelPermalink }}"></script>
{{ end }}

{{ if in .Params.Libraries "mermaid" }}
  {{ printf "<script defer src=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" title=\"mermaid\"></script>" $js.mermaid.url $js.mermaid.sri | safeHTML }}
{{ end }}

{{ if in .Params.Libraries "katex" }}
  {{ printf "<link rel=\"stylesheet\" href=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\">" $css.katex.url $css.katex.sri | safeHTML }}
  {{ printf "<script defer src=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" title=\"katex\"></script>" $js.katex.url $js.katex.sri | safeHTML }}
  {{ printf "<script defer src=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" title=\"katex\"></script>" $js.katex_auto_render.url $js.katex_auto_render.sri | safeHTML }}
{{ end }}

{{ if in .Params.Libraries "flowchartjs" }}
  {{ printf "<script defer src=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" title=\"raphael\"></script>" $js.raphael.url $js.raphael.sri | safeHTML }}
  {{ printf "<script defer src=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" title=\"flowchartjs\"></script>" $js.flowchartjs.url $js.flowchartjs.sri | safeHTML }}
{{ end }}

{{ if in .Params.Libraries "mathjax" }}
  {{ printf "<script defer src=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" title=\"mathjax\"></script>" $js.mathjax.url $js.mathjax.sri | safeHTML }}
{{ end }}

{{ if in .Params.Libraries "msc" }}
  {{ printf "<script defer src=\"%s\" crossorigin=\"anonymous\" title=\"webfont\"></script>" $js.webfont.url | safeHTML }}
  {{ printf "<script defer src=\"%s\" crossorigin=\"anonymous\" title=\"snap_svg\"></script>" $js.snap_svg.url | safeHTML }}
  {{ printf "<script defer src=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" title=\"lodash\"></script>" $js.lodash.url $js.lodash.sri | safeHTML }}
  {{ printf "<script defer src=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" title=\"sequence_diagram\"></script>" $js.sequence_diagram.url $js.sequence_diagram.sri | safeHTML }}
  {{ printf "<link rel=\"stylesheet\" href=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\">" $css.sequence_diagram.url $css.sequence_diagram.sri | safeHTML }}
{{ end }}

{{ if in .Params.Libraries "chart" }}
  {{ printf "<script defer src=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" title=\"chart\"></script>" $js.chart.url $js.chart.sri | safeHTML }}
{{ end }}

{{ if in .Params.Libraries "wavedrom" }}
  {{ printf "<script defer src=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" title=\"wavedrom\"></script>" $js.wavedrom.url $js.wavedrom.sri | safeHTML }}
  {{ printf "<script defer src=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" title=\"wavedrom_skin\"></script>" $js.wavedrom_skin.url $js.wavedrom_skin.sri | safeHTML }}
{{ end }}

{{ if in .Params.Libraries "viz" }}
  {{ printf "<script defer src=\"%s\" crossorigin=\"anonymous\" title=\"viz\"></script>" $js.viz.url | safeHTML }}
  {{ printf "<script defer src=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" title=\"viz_render\"></script>" $js.viz_render.url $js.viz_render.sri | safeHTML }}
{{ end }}


<script>
  window.onload = function() {
    // syntax highlight
    (function () {
      document.querySelectorAll('.chroma>table')
        .forEach((element) => {
          const sub = element.querySelector('code[data-lang]');
          if (sub) {
            element.setAttribute('data-lang', mapLang(sub.getAttribute('data-lang')));
          } else {
            element.setAttribute('data-lang', 'Code');
            $(element).addClass('chroma');
          }
        }
      );
    })();

    function mapLang(name) {
      return {
        coffeescript: 'CoffeeScript',
        cpp: 'C++',
        cs: 'C#',
        css: 'CSS',
        html: 'HTML',
        http: 'HTTP',
        js: 'JavaScript',
        json: 'JSON',
        objectivec: 'Objective-C',
        php: 'PHP',
        sql: 'SQL',
        toml: 'TOML',
        ts: 'TypeScript',
        typescript: 'TypeScript',
        xml: 'XML',
        yaml: 'YAML',
      }[name] || name.toUpperCase();
    }

    // search
    runSearch();

    var navbar = $('.navbar');

    // toc
    {{ $enableToc := ($.Param "enableToc") }}
    var enableToc = JSON.parse({{ $enableToc | jsonify }});
    
    if (enableToc) {
      $("#toc").toc({ content: ".single__contents", headings: "h1,h2,h3,h4" });
      $('#toc > li').each(function () {
        $(this).find('ul').css('display', 'none');
      });
      $('#toc a').each(function () {
        $(this).click(function () {
          navbar.removeClass('navbar--show');
          navbar.removeClass('navbar--hide');
          navbar.addClass('navbar--hide');

          $(".single__contents :header").each(function () {
            $('.toc a').removeClass('active');
          });
          $(this).addClass('active');

          $('#toc > li').each(function () {
            $(this).find('ul').css('display', 'none');
          });
          $(this).next().css('display', 'block');
          $(this).parents('ul').css('display', 'block');
        });
      });

      // toc visibility
      $("#toggle-toc").change(function () {
        if (this.checked) {
          $('.toc').fadeIn(200);
        } else {
          $('.toc').fadeOut(200);
        }
      });
    }    

    // Add link button for every
    var text, clip = new ClipboardJS('.anchor');
    var headers = $('.single__contents :header').not('h6').not('h5');
    headers.append(function (index, html) {
      var element = $(this);
      var url = encodeURI(document.location.origin + document.location.pathname);
      var link = url + "#" + element[0].id;
      return " <span class='anchor hide' data-clipboard-text='" + link + "' style='position: relative;'>" +
        "<span style='font-size: 1rem; position: absolute; right: -2rem; top: 50%; transform: translateY(-50%)'>🔗</span>" +
        "</span>"
        ;
    });
    headers.on('mouseenter', function () {
      $(this).find('.anchor').attr('class', 'anchor');
    });
    headers.on('mouseleave', function () {
      $(this).find('.anchor').attr('class', 'anchor hide');
    });

    $(".anchor").on('mouseleave', function (e) {
      $(this).attr('aria-label', null).removeClass('tooltipped tooltipped-s tooltipped-w');
    });

    clip.on('success', function (e) {
      e.clearSelection();
      $(e.trigger).attr('aria-label', 'Link copied to clipboard!').addClass('tooltipped tooltipped-s');
    });

    $('pre.chroma').not(':has(code)').each(function() {
      $(this).not(':has(span)').wrap('<code style="font-size: 1rem;"></code>');
    });

    // clipboard
    var clipInit = false;
    $('code').each(function () {
      var code = $(this),
        text = code.text();

      if (text.length > 30) {
        if (!clipInit) {
          var text, clip = new ClipboardJS('.copy-to-clipboard', {
            text: function (trigger) {
              text = $(trigger).prev('code').text();
              return text.replace(/^\$\s/gm, '');
            }
          });

          var inPre;
          clip.on('success', function (e) {
            e.clearSelection();
            inPre = $(e.trigger).parent().prop('tagName') == 'PRE';
            $(e.trigger).attr('aria-label', 'Copied to clipboard!').addClass('tooltipped tooltipped-' + (inPre ? 'w' : 's'));
          });

          clip.on('error', function (e) {
            inPre = $(e.trigger).parent().prop('tagName') == 'PRE';
            $(e.trigger).attr('aria-label', fallbackMessage(e.action)).addClass('tooltipped tooltipped-' + (inPre ? 'w' : 's'));
            $(document).one('copy', function () {
              $(e.trigger).attr('aria-label', 'Copied to clipboard!').addClass('tooltipped tooltipped-' + (inPre ? 'w' : 's'));
            });
          });

          clipInit = true;
        }

        var notAllowedClass = ['language-mermaid', 'language-viz', 'language-wave', 'language-chart', 'language-msc', 'language-flowchart'];
        var isNotAllowedIncluded = false;
        var curClassName = code.attr('class');

        for (let str of notAllowedClass) {
          if (curClassName && curClassName.startsWith(str)) {
            isNotAllowedIncluded = true;
            break;
          } 
        }

        if (!isNotAllowedIncluded) {
          code.after('<span class="copy-to-clipboard" title="Copy to clipboard" />');
          code.next('.copy-to-clipboard').on('mouseleave', function () {
            $(this).attr('aria-label', null).removeClass('tooltipped tooltipped-s tooltipped-w');
          });
        }        
      }
    });

    // gallery
    {{ $enablePhotoSwipe := ($.Param "enablePhotoSwipe") }}
    var enablePhotoSwipe = JSON.parse({{ $enablePhotoSwipe | jsonify }});
    
    if (enablePhotoSwipe) {
      var pswpElement = $('.pswp')[0];
      var imgElements = $('.single__contents').find('img');
      var items = [];

      imgElements.each(function (i, v) {
        $(this).click(function (e) {
          initGallery(i);
        });
        $(this).css('cursor', 'pointer');
        items.push({
          src: v['src'],
          w: 0,
          h: 0,
          title: filename(v['src']),
        });
      });

      function filename(str) {
        var s = str.replace(/\\/g, '/');
        s = s.substring(s.lastIndexOf('/') + 1);
        return str ? s.replace(/[?#].+$/, '') : s.split('.')[0];
      }

      function initGallery(index) {
        var options = { index: index };
        var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options);
        gallery.listen('imageLoadComplete', function (index, item) {
          if (item.h < 1 || item.w < 1) {
            let img = new Image();
            img.onload = () => {
              item.w = img.width;
              item.h = img.height;
              gallery.invalidateCurrItems();
              gallery.updateSize(true);
            }
            img.src = item.src;
          }
        });
        gallery.init();
      }
    }

    // mermaid
    {{ $lib := .Params.libraries }}
    var lib = JSON.parse({{ $lib | jsonify }});

    if (lib && lib.includes('mermaid')) {
      {{ $themeVariant := (index .Site.Params.themeOptions 0) }}
      var themeVariant = localStorage.getItem('theme') || JSON.parse({{ $themeVariant | jsonify }});

      if (themeVariant === "dark" || themeVariant === "hacker") {
        mermaid.initialize({ theme: 'dark' });
      } else {
        mermaid.initialize({ theme: 'default' });
      }
      
      let mermaids = [];
      [].push.apply(mermaids, document.getElementsByClassName('language-mermaid'));
      for (i = 0; i < mermaids.length; i++) {
        $(mermaids[i]).unwrap('pre');
        $(mermaids[i]).replaceWith(function () {
          return $("<div />").append($(this).contents()).addClass('mermaid').css('padding', '34px 4px 6px');
        });
      }

      /*$('code.language-mermaid:odd').each(function() {
        $(this).unwrap('pre');
        $(this).replaceWith(function () {
          return $("<div />").append($(this).contents()).addClass('mermaid').css('padding', '34px 4px 6px');
        });
      });

      $('code.language-mermaid').each(function (index, node) {
        $(this).css('display', 'none');
      });*/
    }

    // katex
    if (lib && lib.includes('katex')) {
      var mathElements = document.getElementsByClassName('math');
      var options = [
        { left: "$$", right: "$$", display: true },
        { left: "\\(", right: "\\)", display: false },
        { left: "\\[", right: "\\]", display: true }
      ];

      renderMathInElement(document.querySelector('.single__contents'), options);
    }

    // flowchart.js
    if (lib && lib.includes('flowchartjs')) {
      {{ $flowchartjs := .Site.Data.flowchartjs }}
      var options = JSON.parse({{ $flowchartjs | jsonify }});

      var flowchartPrefix = "language-flowchart";
      var index = 0;
      Array.prototype.forEach.call(document.querySelectorAll("[class^=" + flowchartPrefix + "]"), function(x){
          x.style.display = 'none'
          x.parentNode.style.backgroundColor = "transparent"
          jsonContent = x.innerText;

          node0 = document.createElement('div');
          node0.id = 'flowchart' + index;
          x.parentNode.insertBefore(node0, x);

          var diagram = flowchart.parse(jsonContent);
          diagram.drawSVG("flowchart"+index, options);

          index +=1;
      });
      
      /*$('code.language-flowchart:odd').each(function (index, node) {
        var diagramContent = $(this).contents();
        $(this).closest('table').attr('data-content', 'FLOWCHART');
        $(this).unwrap('pre');
        $(this).replaceWith(function () {
          return $("<div id='diagram' data-content='flowchart'></div>").append(diagramContent.text()).addClass('diagram').css('padding', '34px 4px 6px').css('margin-top', '40px');
        });      

        var diagram = flowchart.parse(diagramContent.text());      
        $('#diagram').empty();
        diagram.drawSVG('diagram', options);      
      });    

      $('code.language-flowchart').each(function (index, node) {      
        $(this).unwrap('pre');
        $(this).replaceWith(function () {
          return $("<div></div>");
        });      
      });*/
    }

    // mathjax
    if (lib && lib.includes('mathjax')) {
      window.MathJax = {
        tex: {
          inlineMath: [['$', '$'], ['\\(', '\\)']],
          displayMath: [['$$', '$$'], ['\\[', '\\]']],
          processEscapes: false,
          packages: { '[+]': ['noerrors'] }
        },
        loader: {
          load: ['[tex]/noerrors']
        },
      };
    }

    // js-sequence-diagram
    if (lib && lib.includes('msc')) {
      {{ $msc := .Site.Data.msc }}
      var options = JSON.parse({{ $msc | jsonify }});    

      var index = 0;
      var chartPrefix = "language-msc";
      Array.prototype.forEach.call(document.querySelectorAll("[class^=" + chartPrefix + "]"), function (x) {
        x.style.display = 'none'
        x.parentNode.style.backgroundColor = "transparent"
        jsonContent = x.innerText;
        node0 = document.createElement('div');
        node0.id = 'msc' + index;
        x.parentNode.insertBefore(node0, x);
        var diagram = Diagram.parse(jsonContent);
        diagram.drawSVG("msc" + index, options);
        index += 1;
      });

      /*$('code.language-msc:odd').each(function() {
        $(this).unwrap('pre');
        $(this).replaceWith(function () {
          return $("<div />").append($(this).contents()).addClass('diagram');
        });
      });
      $(".diagram").sequenceDiagram(options);

      $('code.language-msc').each(function (index, node) {
        $(this).css('display', 'none');
      });*/
    }

    // chart.js
    if (lib && lib.includes('chart')) {
      var borderColor = "#666";
      var bgColor = "#ddd";
      var borderWidth = 2;

      Chart.defaults.global.elements.rectangle.borderWidth = borderWidth;
      Chart.defaults.global.elements.rectangle.borderColor = borderColor;
      Chart.defaults.global.elements.rectangle.backgroundColor = bgColor;

      Chart.defaults.global.elements.line.borderWidth = borderWidth;
      Chart.defaults.global.elements.line.borderColor = borderColor;
      Chart.defaults.global.elements.line.backgroundColor = bgColor;

      Chart.defaults.global.elements.point.borderWidth = borderWidth;
      Chart.defaults.global.elements.point.borderColor = borderColor;
      Chart.defaults.global.elements.point.backgroundColor = bgColor;

      var chartPrefix = "language-chart";
      var index = 0;
      Array.prototype.forEach.call(document.querySelectorAll("[class^=" + chartPrefix + "]"), function (x) {
        x.style.display = 'none'
        x.parentNode.style.backgroundColor = "transparent"
        jsonContent = x.innerText;
        node0 = document.createElement('canvas');
        node0.height = 200;
        node0.style.height = 200;
        node0.id = 'myChart' + index;
        source = JSON.parse(jsonContent);
        x.parentNode.insertBefore(node0, x);
        var ctx = document.getElementById('myChart' + index).getContext('2d');
        var myChart = new Chart(ctx, source);
        index += 1;
      });      

      /*$('code.language-chart:odd').each(function (index, node) {
        $(this).unwrap('pre');

        node0 = document.createElement('canvas');
        node0.height = 200;
        node0.style.height = 200;
        node0.id = 'myChart' + index;
        source = JSON.parse(node.innerText);
        node.parentNode.insertBefore(node0, node);
        var ctx = document.getElementById('myChart' + index).getContext('2d');
        var myChart = new Chart(ctx, source);

        $(this).closest('td').css('padding', '40px 8px 8px');
        $(this).hide();
      });

      $('code.language-chart:even').each(function (index, node) {
        $(this).css('display', 'none');
      });*/
      
    }

    // wavedrom
    if (lib && lib.includes('wavedrom')) {
      /*$('code.language-wave:odd').each(function (index, node) {
        $(this).unwrap('pre');

        node0 = document.createElement('div');
        node0.id = 'WaveDrom_Display_' + index;
        source = JSON.parse(node.innerText);
        node.parentNode.insertBefore(node0, node);

        WaveDrom.RenderWaveForm(index, source, "WaveDrom_Display_");

        $(this).closest('td').css('padding', '40px 12px 12px 0');
        $(this).hide();
      });

      $('code.language-wave').each(function (index, node) {
        $(this).css('display', 'none');
      });*/

      var wavePrefix = "language-wave";
      var index = 0;
      Array.prototype.forEach.call(document.querySelectorAll("[class^=" + wavePrefix + "]"), function (x) {
        x.style.display = 'none'
        x.parentNode.style.backgroundColor = "transparent"
        jsonContent = x.innerText;
        node0 = document.createElement('div');
        node0.id = 'WaveDrom_Display_' + index;
        source = JSON.parse(jsonContent);
        x.parentNode.insertBefore(node0, x);
        WaveDrom.RenderWaveForm(index, source, "WaveDrom_Display_");
        index += 1;
      });
    }

    // viz diagram
    if (lib && lib.includes('viz')) {
      /*var vizPrefix = "language-viz-";
      $('pre[class*="language-viz-"]:odd').each(function (index, node) {
        $(this).unwrap('pre');

        var engine;
        node.getAttribute("class").split(" ").forEach(function (cls) {
          if (cls.startsWith(vizPrefix)) {
            engine = cls.substr(vizPrefix.length);
          }
        });
        var viz = new Viz();
        viz.renderSVGElement(node.innerText, { engine: engine })
          .then(function (element) {
            element.style.width = "100%";
            node.parentNode.insertBefore(element, node);
          });
        $(this).closest('td').css('padding', '40px 0 16px 0');
        $(this).hide();
      });
      $('code[class*="language-viz-"]:even').each(function (index, node) {
        $(this).hide();
      });*/

      var vizPrefix = "language-viz-";
      Array.prototype.forEach.call(document.querySelectorAll("[class^=" + vizPrefix + "]"), function (x) {
        x.style.display = 'none'
        x.parentNode.style.backgroundColor = "transparent"
        var engine;
        x.getAttribute("class").split(" ").forEach(function (cls) {
          if (cls.startsWith(vizPrefix)) {
            engine = cls.substr(vizPrefix.length);
          }
        });
        var viz = new Viz();
        viz.renderSVGElement(x.innerText, { engine: engine })
          .then(function (element) {
            element.style.width = "100%";
            x.parentNode.insertBefore(element, x);
          })
      });
    }
  }
</script>