<commit_before>/* global kuromoji */
import d3 from "d3"
import "kuromoji"

var i,j,k,l;

var width = 1320,
    height = 660;

var color = d3.scale.category20c();

var force = d3.layout.force()
    .charge(-120)
    .linkDistance(120)
    .size([width, height]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

document.getElementById('load-button').addEventListener('click', function () {
        var file = document.getElementById('file-input').files[0];
        var reader = new FileReader();
        reader.onload = function(event) {
            var data = JSON.parse(event.target.result);
            console.log(data);

            kuromoji.builder({dicPath: 'dict/'}).build((err, tokenizer) => {
              const path = tokenizer.tokenize(data[0].a); //1集計単位ごとにこの関数を用いよう
              console.log(path);

              var keitaisokaiseki = new Array; //このlengthは段落数
              var reasonMatrix = new Array;

              var buntou;
              var tegakari;
              var toutencount;
              var toutenbasho=0;
              i=0; //iは全データ内で何文字目か
              j=0; //何個目の集計単位か。
              var karabasho;
              var reason;
              var kara="から"
              while(i<path.length){
                tegakari=0;//手がかりがあるか
                keitaisokaiseki[j] = new Array; //一文
                reasonMatrix[j] = new Array;
                buntou=i; //現在の文の文頭が何単語目か
                toutencount=0
                reason=1;
                //まずは手がかり語があるか探す

                while(i<path.length){ //kara捜索
                  if(path[i].basic_form==kara){ //手がかり語があったら3区間指定
                    karabasho = i;
                    while(i>0){
                      i=i-1;
                      if(path[i].basic_form=="。"||path[i].basic_form=="？"||path[i].basic_form=="?"||path[i].basic_form=="、"){

                          buntou=i;
                          toutencount=0;
                          break;

                      }
                    }
                    if(i==0){
                      buntou=0;
                    }
                    console.log(buntou);
                    tegakari=1;
                    break;//「から」が見つかった
                  }
                  i++;
                }

                //手がかりがなければbreak
                if(i==path.length){
                  console.log("All kara was found.");
                  break;
                }

                i=buntou
                toutencount=0;
                k=0; //集計単位内で何文字目か
                while(i<path.length){
                  if(i==karabasho+1){
                    reason=0;
                  }
                  if(path[i].basic_form=="。"||path[i].basic_form=="？"||path[i].basic_form=="?"||path[i].basic_form=="、"){
                    if(toutencount<3){
                      i++;
                      toutencount++;
                      continue;
                    } else{
                      i++;
                      toutencount=0;
                      break;//3区間終了
                    }
                  }
                  if(path[i].basic_form==kara||path[i].basic_form=="たぶん"||path[i].basic_form=="られる"||path[i].basic_form=="する"||path[i].basic_form=="なる"||path[i].basic_form=="れる"||path[i].basic_form=="思う"||path[i].basic_form=="自分"||path[i].basic_form=="ちょっと"){
                    i++;
                    continue;
                  }
                  if(path[i].pos=="助詞"||path[i].pos=="助動詞"||path[i].pos=="接続詞"||path[i].pos=="記号"||path[i].pos_detail_1=="非自立"||path[i].basic_form=="それで"||path[i].basic_form=="こう"||path[i].basic_form=="そう"||path[i].pos_detail_1=="代名詞"){
                      i++;
                      continue;
                  }
                  if(path[i].basic_form=="もう"||path[i].basic_form=="こんなに"||path[i].basic_form=="そんな"||path[i].basic_form=="さん"){
                    i++;
                    continue;
                  }

                  keitaisokaiseki[j][k] = path[i].basic_form;
                  reasonMatrix[j][k] = reason;
                  i++;
                  k++;
                }
                if(i==path.length){break;}//keitaisokaiseki作成完了
                i=karabasho+1;
                j++;
              }

            //以下、想定していた形態素解析後の結果から、共起ネットワークのノード・エッジ作成へ

            console.log(keitaisokaiseki);
            console.log(reasonMatrix);

            var tangoset = new Set();

            for(i=0;i<keitaisokaiseki.length;++i){

              for(j=0;j<keitaisokaiseki[i].length;++j){
                tangoset.add({name:keitaisokaiseki[i][j],
                              group:reasonMatrix[i][j]

                            });

            }
          }

          var tangosett = new Array;;

          tangosett = Array.from(tangoset).map(function(t) {
            return {t};
            // body...
          });

            var miserables={"nodes":new Array,"links":new Array};

            for(i=0;i<tangosett.length;i++){
              miserables.nodes[i]=tangosett[i].t;
            }

            console.log(miserables.nodes);
            console.log(miserables.nodes.length);
/*
            for(k=0;k<miserables.nodes.length;++k){

              miserables.nodes[k].group =1;//ゆくゆくは媒介中心性に
            }*/
            //node作成終了。miserables.nodes.lengthがtangosetになってるはず

            var danrakusuu = keitaisokaiseki.length;

            //あとはlinksの作成だけ
            //まずはlistをつくる
            var list = new Array(keitaisokaiseki.length);
            //list作成
            //keitaisokaisekiとnodesを照らしあわせる
            for(i=0;i<keitaisokaiseki.length;++i){//danrakusuuはkeitaisokaisekiとlistで共
              list[i] = new Array(miserables.nodes.length);
              for(j=0;j<keitaisokaiseki[i].length;++j){
                for(k=0;k<miserables.nodes.length;++k){
                  if(keitaisokaiseki[i][j]==miserables.nodes[k].name){
                    list[i][k]=1;

                  }
                }
              }
            }
            console.log(list);
            //listはi*k

            //listからmiserables.linksとlist3をつくる

            var x,y,z;

            var edge=-1;

                for(k=0;k<miserables.nodes.length;++k){

                  for(l=k+1;l<miserables.nodes.length;++l){//別の単語を見る
                    //現在単語2個の組み合わせを選択中

                    //ここから段落を指定して縦になめる

                    for(i=0;i<keitaisokaiseki.length;++i){
                      x=list[i][k];
                      y=list[i][l];

                      if(x==1 && y==1){

                        miserables.links.push({source:l,target:k,value:0});
                        edge++;//最初のedgeが0
                        break;
                      }
                    }
                    //とりあえずエッジつくってbreak
                    //こっからvalueを与える
                    for(i=0;i<keitaisokaiseki.length;++i){
                      x=list[i][k];
                      y=list[i][l];
                      if(x==1 && y==1){
                        z = miserables.links[edge].value;
                        z++;
                        miserables.links[edge].value = z;
                      }
                    }
                  }
                }
                console.log(miserables.links);

            //以上計算中

            var graph = miserables;

                force
                    .nodes(graph.nodes)
                    .links(graph.links)
                    .start();

                var link = svg.selectAll(".link")
                    .data(graph.links)
                  .enter().append("line")
                    .attr("class", "link")
                    .style("stroke-width", function(d) { return Math.sqrt(d.value); });

              var node = svg.selectAll(".node")
                  .data(graph.nodes)
                .enter().append("text")
                  .attr("class", "node")
                  .style("fill", function(d) {
                    if(d.group==1){
                      return "red";
                    } else{
                      return "blue";
                    }

                  })
                  .call(force.drag)
                  .text(function(d) { return d.name; });

                force.on("tick", function() {
                  link.attr("x1", function(d) { return d.source.x; })
                      .attr("y1", function(d) { return d.source.y; })
                      .attr("x2", function(d) { return d.target.x; })
                      .attr("y2", function(d) { return d.target.y; });

                  node.attr("x", function(d) { return d.x; })
                      .attr("y", function(d) { return d.y; });
                });
                });
        };
        reader.readAsText(file);

        /*clustering*/

  });

  var cluster = require('hierarchical-clustering');
  var colors = [
  [20, 20, 80],
  [22, 22, 90],
  [250, 255, 253],
  [100, 54, 255]
  ];

  // Euclidean distance
  function distance(a, b) {
  var d = 0;
  for (var i = 0; i < a.length; i++) {
  d += Math.pow(a[i] - b[i], 2);
  }
  return Math.sqrt(d);
  }

  // Single-linkage clustering
  function linkage(distances) {
  return Math.min.apply(null, distances);
  }

  var levels = cluster({
  input: colors,
  distance: distance,
  linkage: linkage,
  minClusters: 2, // only want two clusters
  });

  var clusters = levels[levels.length - 1].clusters;
  console.log(clusters);
  // => [ [ 2 ], [ 3, 1, 0 ] ]
  clusters = clusters.map(function (cluster) {
  return cluster.map(function (index) {
  return colors[index];
  });
  });
  console.log(clusters);
  // => [ [ [ 250, 255, 253 ] ],
  // => [ [ 100, 54, 255 ], [ 22, 22, 90 ], [ 20, 20, 80 ] ] ]

          var stackdataArr = [
              [{x:1,y:3},{x:2,y:5},{x:3,y:7},{x:4,y:3},{x:5,y:5},{x:6,y:7}],
              [{x:1,y:2},{x:2,y:4},{x:3,y:9},{x:4,y:7},{x:5,y:6},{x:6,y:4}],
              [{x:1,y:1},{x:2,y:8},{x:3,y:5},{x:4,y:3},{x:5,y:5},{x:6,y:7}],
              [{x:1,y:8},{x:2,y:6},{x:3,y:3},{x:4,y:2},{x:5,y:7},{x:6,y:4}]
          ];
          var stack = d3.layout.stack()
              .x(function(d){return 1;})
              .y(function(d){return d.y;})
              .values(function(d){return d;});
          var stackdata = stack(stackdataArr);
          var max = d3.max(stackdata[stackdata.length - 1], function(d){return d.y + d.y0;});
          var scaleX = d3.scale.linear().domain([0,6]).range([0,width/2]);
          var scaleY = d3.scale.linear().domain([0,max]).range([0,200]);
          var colors = ["blue","purple","red","orange","yellow","#0f0","green"];
          var area = d3.svg.area()
              .x(function(d,i){return i * width/10})
              .y0(function(d){return 200})
              .y1(function(d){return 200 - scaleY(d.y+d.y0)});
          svg.selectAll("path")
              .data(stackdata.reverse())
              .enter()
              .append("path")
              .attr("d", area)
              .attr("fill",function(d,i){return colors[i]});

              //grid line
              //引数はstart,stop,stepの順
              //[190,170,150,130,110,90,70,50,30,10]と同等
            var range = d3.range((width/2)-(width/20),4,-width/10);
            svg.selectAll("line.v")
              .data(range).enter().append("line")
              .attr("x1", function(d,i){return d;}).attr("y1", 0)
              .attr("x2", function(d,i){return d;}).attr("y2", 200);
            svg.selectAll("line")
              .attr("stroke", "black")

//チェックボックス

              function boxCheck(){

                //チェックされた項目を記録する変数
                var str="";

                //for文でチェックボックスを１つずつ確認
                for( i=0; i<6; i++ )
                {
                  //チェックされているか確認する
                  if( document.chbox.elements[i].checked )
                  {
                    //変数strが空でない時、区切りのコンマを入れる
                    if( str != "" ) str=str+",";

                    //チェックボックスのvalue値を変数strに入れる
                    str=str+document.chbox.elements[i].value;
                  }
                }

                //strが空の時、警告を出す
                if( str=="" ){
                   alert( "どれか選択してください。" );
                }else{
                  alert( str + "が選択されました。" );
                }
              }
<commit_msg>stroke-width<commit_after>/* global kuromoji */
import d3 from "d3"
import "kuromoji"

document.write("JavaScriptはONです。");

var i,j,k,l;

var width = 1320,
    height = 660;

var color = d3.scale.category20c();

var force = d3.layout.force()
    .charge(-120)
    .linkDistance(120)
    .size([width, height]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

document.getElementById('load-button').addEventListener('click', function () {
        var file = document.getElementById('file-input').files[0];
        var reader = new FileReader();
        reader.onload = function(event) {
            var data = JSON.parse(event.target.result);
            console.log(data);

            kuromoji.builder({dicPath: 'dict/'}).build((err, tokenizer) => {
              const path = tokenizer.tokenize(data[0].a); //1集計単位ごとにこの関数を用いよう
              console.log(path);

              var keitaisokaiseki = new Array; //このlengthは段落数
              var reasonMatrix = new Array;

              var buntou;
              var tegakari;
              var toutencount;
              var toutenbasho=0;
              i=0; //iは全データ内で何文字目か
              j=0; //何個目の集計単位か。
              var karabasho;
              var reason;
              var kara="から"
              while(i<path.length){
                tegakari=0;//手がかりがあるか
                keitaisokaiseki[j] = new Array; //一文
                reasonMatrix[j] = new Array;
                buntou=i; //現在の文の文頭が何単語目か
                toutencount=0
                reason=1;
                //まずは手がかり語があるか探す

                while(i<path.length){ //kara捜索
                  if(path[i].basic_form==kara){ //手がかり語があったら3区間指定
                    karabasho = i;
                    while(i>0){
                      i=i-1;
                      if(path[i].basic_form=="。"||path[i].basic_form=="？"||path[i].basic_form=="?"||path[i].basic_form=="、"){

                          buntou=i;
                          toutencount=0;
                          break;

                      }
                    }
                    if(i==0){
                      buntou=0;
                    }
                    console.log(buntou);
                    tegakari=1;
                    break;//「から」が見つかった
                  }
                  i++;
                }

                //手がかりがなければbreak
                if(i==path.length){
                  console.log("All kara was found.");
                  break;
                }

                i=buntou
                toutencount=0;
                k=0; //集計単位内で何文字目か
                while(i<path.length){
                  if(i==karabasho+1){
                    reason=0;
                  }
                  if(path[i].basic_form=="。"||path[i].basic_form=="？"||path[i].basic_form=="?"||path[i].basic_form=="、"){
                    if(toutencount<3){
                      i++;
                      toutencount++;
                      continue;
                    } else{
                      i++;
                      toutencount=0;
                      break;//3区間終了
                    }
                  }
                  if(path[i].basic_form==kara||path[i].basic_form=="たぶん"||path[i].basic_form=="られる"||path[i].basic_form=="する"||path[i].basic_form=="なる"||path[i].basic_form=="れる"||path[i].basic_form=="思う"||path[i].basic_form=="自分"||path[i].basic_form=="ちょっと"){
                    i++;
                    continue;
                  }
                  if(path[i].pos=="助詞"||path[i].pos=="助動詞"||path[i].pos=="接続詞"||path[i].pos=="記号"||path[i].pos_detail_1=="非自立"||path[i].basic_form=="それで"||path[i].basic_form=="こう"||path[i].basic_form=="そう"||path[i].pos_detail_1=="代名詞"){
                      i++;
                      continue;
                  }
                  if(path[i].basic_form=="もう"||path[i].basic_form=="こんなに"||path[i].basic_form=="そんな"||path[i].basic_form=="さん"){
                    i++;
                    continue;
                  }

                  keitaisokaiseki[j][k] = path[i].basic_form;
                  reasonMatrix[j][k] = reason;
                  i++;
                  k++;
                }
                if(i==path.length){break;}//keitaisokaiseki作成完了
                i=karabasho+1;
                j++;
              }

            //以下、想定していた形態素解析後の結果から、共起ネットワークのノード・エッジ作成へ

            console.log(keitaisokaiseki);
            console.log(reasonMatrix);

            var tangoset = new Set();

            for(i=0;i<keitaisokaiseki.length;++i){

              for(j=0;j<keitaisokaiseki[i].length;++j){
                tangoset.add({name:keitaisokaiseki[i][j],
                              group:reasonMatrix[i][j]

                            });

            }
          }

          var tangosett = new Array;;

          tangosett = Array.from(tangoset).map(function(t) {
            return {t};
            // body...
          });

            var miserables={"nodes":new Array,"links":new Array};

            for(i=0;i<tangosett.length;i++){
              miserables.nodes[i]=tangosett[i].t;
            }

            console.log(miserables.nodes);
            console.log(miserables.nodes.length);
/*
            for(k=0;k<miserables.nodes.length;++k){

              miserables.nodes[k].group =1;//ゆくゆくは媒介中心性に
            }*/
            //node作成終了。miserables.nodes.lengthがtangosetになってるはず

            var danrakusuu = keitaisokaiseki.length;

            //あとはlinksの作成だけ
            //まずはlistをつくる
            var list = new Array(keitaisokaiseki.length);
            //list作成
            //keitaisokaisekiとnodesを照らしあわせる
            for(i=0;i<keitaisokaiseki.length;++i){//danrakusuuはkeitaisokaisekiとlistで共
              list[i] = new Array(miserables.nodes.length);
              for(j=0;j<keitaisokaiseki[i].length;++j){
                for(k=0;k<miserables.nodes.length;++k){
                  if(keitaisokaiseki[i][j]==miserables.nodes[k].name){
                    list[i][k]=1;

                  }
                }
              }
            }
            console.log(list);
            //listはi*k

            //listからmiserables.linksとlist3をつくる

            var x,y,z;

            var edge=-1;

                for(k=0;k<miserables.nodes.length;++k){

                  for(l=k+1;l<miserables.nodes.length;++l){//別の単語を見る
                    //現在単語2個の組み合わせを選択中

                    //ここから段落を指定して縦になめる

                    for(i=0;i<keitaisokaiseki.length;++i){
                      x=list[i][k];
                      y=list[i][l];

                      if(x==1 && y==1){

                        miserables.links.push({source:l,target:k,value:0});
                        edge++;//最初のedgeが0
                        break;
                      }
                    }
                    //とりあえずエッジつくってbreak
                    //こっからvalueを与える
                    for(i=0;i<keitaisokaiseki.length;++i){
                      x=list[i][k];
                      y=list[i][l];
                      if(x==1 && y==1){
                        z = miserables.links[edge].value;
                        z++;
                        miserables.links[edge].value = z;
                      }
                    }
                  }
                }
                console.log(miserables.links);

            //以上計算中

            var graph = miserables;

                force
                    .nodes(graph.nodes)
                    .links(graph.links)
                    .start();

                var link = svg.selectAll(".link")
                    .data(graph.links)
                  .enter().append("line")
                    .attr("class", "link")
                    .style("stroke-width", function(d) { return Math.sqrt(d.value); });

              var node = svg.selectAll(".node")
                  .data(graph.nodes)
                .enter().append("text")
                  .attr("class", "node")
                  .style("fill", function(d) {
                    if(d.group==1){
                      return "red";
                    } else{
                      return "blue";
                    }

                  })
                  .call(force.drag)
                  .text(function(d) { return d.name; });

                force.on("tick", function() {
                  link.attr("x1", function(d) { return d.source.x; })
                      .attr("y1", function(d) { return d.source.y; })
                      .attr("x2", function(d) { return d.target.x; })
                      .attr("y2", function(d) { return d.target.y; });

                  node.attr("x", function(d) { return d.x; })
                      .attr("y", function(d) { return d.y; });
                });
                });
        };
        reader.readAsText(file);

        /*clustering*/

  });

  var cluster = require('hierarchical-clustering');
  var colors = [
  [20, 20, 80],
  [22, 22, 90],
  [250, 255, 253],
  [100, 54, 255]
  ];

  // Euclidean distance
  function distance(a, b) {
  var d = 0;
  for (var i = 0; i < a.length; i++) {
  d += Math.pow(a[i] - b[i], 2);
  }
  return Math.sqrt(d);
  }

  // Single-linkage clustering
  function linkage(distances) {
  return Math.min.apply(null, distances);
  }

  var levels = cluster({
  input: colors,
  distance: distance,
  linkage: linkage,
  minClusters: 2, // only want two clusters
  });

  var clusters = levels[levels.length - 1].clusters;
  console.log(clusters);
  // => [ [ 2 ], [ 3, 1, 0 ] ]
  clusters = clusters.map(function (cluster) {
  return cluster.map(function (index) {
  return colors[index];
  });
  });
  console.log(clusters);
  // => [ [ [ 250, 255, 253 ] ],
  // => [ [ 100, 54, 255 ], [ 22, 22, 90 ], [ 20, 20, 80 ] ] ]

          var stackdataArr = [
              [{x:1,y:3},{x:2,y:5},{x:3,y:7},{x:4,y:3},{x:5,y:5},{x:6,y:7}],
              [{x:1,y:2},{x:2,y:4},{x:3,y:9},{x:4,y:7},{x:5,y:6},{x:6,y:4}],
              [{x:1,y:1},{x:2,y:8},{x:3,y:5},{x:4,y:3},{x:5,y:5},{x:6,y:7}],
              [{x:1,y:8},{x:2,y:6},{x:3,y:3},{x:4,y:2},{x:5,y:7},{x:6,y:4}]
          ];
          var stack = d3.layout.stack()
              .x(function(d){return 1;})
              .y(function(d){return d.y;})
              .values(function(d){return d;});
          var stackdata = stack(stackdataArr);
          var max = d3.max(stackdata[stackdata.length - 1], function(d){return d.y + d.y0;});
          var scaleX = d3.scale.linear().domain([0,6]).range([0,width/2]);
          var scaleY = d3.scale.linear().domain([0,max]).range([0,200]);
          var colors = ["blue","purple","red","orange","yellow","#0f0","green"];
          var area = d3.svg.area()
              .x(function(d,i){return i * width/10})
              .y0(function(d){return 200})
              .y1(function(d){return 200 - scaleY(d.y+d.y0)});
          svg.selectAll("path")
              .data(stackdata.reverse())
              .enter()
              .append("path")
              .attr("d", area)
              .attr("fill",function(d,i){return colors[i]});

              //grid line
              //引数はstart,stop,stepの順
              //[190,170,150,130,110,90,70,50,30,10]と同等
            var range = d3.range((width/2)-(width/20),4,-width/10);
            svg.selectAll("line.v")
              .data(range).enter().append("line")
              .attr("x1", function(d,i){return d;}).attr("y1", 0)
              .attr("x2", function(d,i){return d;}).attr("y2", 200);
            svg.selectAll("line")
              .attr("stroke", "purple")
              .attr("stroke-width", 20)

//チェックボックス

              function boxCheck(){

                //チェックされた項目を記録する変数
                var str="";

                //for文でチェックボックスを１つずつ確認
                for( i=0; i<6; i++ )
                {
                  //チェックされているか確認する
                  if( document.chbox.elements[i].checked )
                  {
                    //変数strが空でない時、区切りのコンマを入れる
                    if( str != "" ) str=str+",";

                    //チェックボックスのvalue値を変数strに入れる
                    str=str+document.chbox.elements[i].value;
                  }
                }

                //strが空の時、警告を出す
                if( str=="" ){
                   alert( "どれか選択してください。" );
                }else{
                  alert( str + "が選択されました。" );
                }
              }
<|endoftext|>


<commit_before>/**
 * User Interface
 */
var UIComponents =
{
    sidebarDropdown : function(title, items) {
        // Generate dropdown and menu
        var dom_dropdown = $('
' + title + '
');
        var dom_menu = $('

');

        // Generate menu entries
        for(item_id in items) {
            var menu_item = items[item_id];
            var dom_menu_item = $('
' + menu_item.title + '
');

            // Append menu entry
            dom_menu.append(dom_menu_item);
        }

        // Append menu
        dom_dropdown.append(dom_menu);

        return dom_dropdown;
    },

    table : function(title, datasource, columns, target) {

        // Clear the target
        target.html('');

        // Build header
        if(title && title.length != 0) {
            var dom_header = $('
' + title + '
');
            target.append(dom_header);
        }

        // Extract fields
        var fields = new Array;
        for(var column_id in columns) {
            if(columns[column_id]["data_key"] !== undefined
               && columns[column_id]["data_key"] !== null
               && columns[column_id]["data_key"].length !== 0)
                fields.push(columns[column_id]["data_key"]);
        }

        // Group up action columns
        var action_column = {
            'formatter' : Formatter.action,
            'sortable' : false,
            'actions' : []
        };

        // Build column config for table
        var columns_config = new Array();
        for(c_index in columns) {
            var column = columns[c_index];

            // Copy basic values
            var column_config = {
                'field' : column.data_key,
                'title' : column.title,
                'visible' : (column.visible == true ? true : false),
                'sortable' : (column.sortable !== undefined ? column.sortable : true)
            }

            // Apply type to column
            if(!column.type) column.type = 'plain';
            switch(column.type) {
                case 'link' :
                    column_config.target = column.target;
                    column_config.formatter = Formatter.link;
                    break;

                case 'email' :
                    column_config.formatter = Formatter.email;
                    break;

                case 'action' :
                    action_column.actions.push({
                        'target' : column.target,
                        'icon' : column.icon
                    });
                    break;

                case 'int' :
                case 'plain' :
                    break;

                default:
                    console.error('Unsupported column type "' + column.type + '"');
            }

            // Add column to table
            if(column.type !== 'action') {
                columns_config.push(column_config);
            }
        }

        // Add action column
        if(action_column.actions.length > 0) {
            columns_config.push(action_column);
        }

        // Build table
        var dom_table = $('

');
        target.append(dom_table);

        dom_table.bootstrapTable({
            url: datasource,
            columns: columns_config,
            sortable: true,
            pagination: true,
            pageSize: 20,
            sidePagination: 'server',
            search: true,
            queryParams: function(params) {
                params.fields = fields.join();
                return params;
            }
        });
    },

    detail : function(title, datasource, fields, dom_target) {

        // Clear the target
        dom_target.html('');

        // Build header
        if(title && title.length != 0) {
            var dom_header = $('
' + title + '
');
            dom_target.append(dom_header);
        }

        // Generate container for the detail view
        var dl_target = $('

');
        dom_target.append(dl_target);

        // Show loading mask
        UIComponents.loadingMask(dl_target);

        // Send a request for data
        $.ajax({
            dataType: 'json',
            url: datasource,
            success: function(data) {

                // Prepare the definition list
                var html = $('

');

                // Go through all the fields
                for(field_id in fields) {
                    var field = fields[field_id];

                    if(field.visible != true) {
                        continue;
                    }

                    var dt = '';
                    var dd = '-';

                    if(field.title !== undefined
                       && field.title !== null) {
                        dt = field.title;
                    }

                    if(data[field.data_key] !== undefined
                       && data[field.data_key] !== null) {

                        var value = data[field.data_key];
                        if(typeof field.store_module !== 'undefined'
                           && typeof field.store_name !== 'undefined'
                           && field.store_module !== null
                           && field.store_name !== null) {
                            value = Stores.getValueForStoreAndKey(field.store_module, field.store_name, value);
                        }

                        // Apply renderer if needed
                        if(field.type !== null && field.type !== '') {
                            dd = Formatter[field.type].call(field, value, data, null);
                        } else {
                            dd = value;
                        }
                    }

                    html.append($('
' + dt + '

' + dd + '
'));
                }

                dl_target.html(html);
            }
        });
    },

    combined : function(title, params, fields, dom_target) {

        // Clear the target
        dom_target.html('');

        // Build header
        if(title && title.length != 0) {
            var dom_header = $('
' + title + '
');
            dom_target.append(dom_header);
        }

        // Generate container for the combined view
        var combined_target = $('

');
        dom_target.append(combined_target);

        // Show loading mask
        UIComponents.loadingMask(combined_target);

        // Iterate over all components
        for(field_id in fields) {
            var field_dom = $('

');
            combined_target.append(field_dom);

            var field = fields[field_id];

            // Split the target into model and view
            var target = Helper.replacePlaceholdersInURL(field.data_key, params)
            target = target.split('/')
            if(target.length >= 3) {

                // Load the view config and handle it
                var first_component = true;
                $.ajax({
                    dataType: 'json',
                    url: '/backend/modules/' +  target[1] + '/views/' + target[2],
                    view_params: target,
                    field_dom: field_dom,
                    success: function(data) {
                        if(first_component) {
                            first_component = false;
                            combined_target.find('.spinner').remove();
                        }
                        UI.applyViewConfig(data, this.view_params.slice(3), this.field_dom);
                    }
                });

            } else {
                console.error('URL "' + url + '" is not a valid target!');
            }
        }
    },

    loadingMask : function(dom_target) {
        var loading_html = $([
            '
',
                '

',
                '

',
            '
'].join(''));

        dom_target.html(loading_html);
    }
}

var UI =
{
    applyViewConfig : function(config, params, dom_target) {

        // Get the main view if no target was defined
        if(typeof dom_target === 'undefined' || dom_target === null) {
            dom_target = $("#main");
        }

        // Handle the type of the view
        switch(config.type) {
            case 'table':
                var datasource = Helper.replacePlaceholdersInURL(config.datasource, params);
                UIComponents.table(config.title, datasource, config.fields, dom_target);
                break;

            case 'detail':
                var datasource = Helper.replacePlaceholdersInURL(config.datasource, params);
                UIComponents.detail(config.title, datasource, config.fields, dom_target);
                break;

            case 'combined':
                UIComponents.combined(config.title, params, config.fields, dom_target);
                break;

            default:
                console.error('Unsupported view type "' + config.type + '"');
        }
    },

    applySidebarConfig : function(sidebar_config) {
        // Load sidebar items
        var sidebar_main_menu = $("#sidebar-main-menu");
        sidebar_main_menu.html('');

        for(var menu_index in sidebar_config) {
            var menu_item = sidebar_config[menu_index];

            var dom_menu_item = UIComponents.sidebarDropdown(menu_item.title, menu_item.items);

            sidebar_main_menu.append(dom_menu_item);
        }

        // Handle Sidebar clicks
        $(".menu-item").click(function() {
            // Switch active sidebar item
            $("li.active").removeClass("active");
            $(this).parent("li").addClass("active");

            // Load view config
             Navigation.navigateToURL(this.href);
        });
    },
};

var Formatter =
{
    email : function(value, row, index) {
        // In case this gets called for an invisible column
        if(!this.visible) return;

        return '' + value + '';
    },

    link : function(value, row, index) {
        // In case this gets called for an invisible column
        if(!this.visible) return;

        // Replace placeholders in target
        var target_parts = this.target.split('/');
        for(part_index in target_parts) {
            if(target_parts[part_index].indexOf(":") == 0) {
                var key = target_parts[part_index].slice(1);
                if(row[key] !== undefined) {
                    target_parts[part_index] = row[key];
                } else {
                    console.error('Column target is referring to undefined key "' + key + '"');
                }
            }
        }
        return '' + value + '';
    },

    action : function(value, row, index) {
        // In case this gets called for an invisible column
        if(!this.visible) return;

        var html = new Array();

        for(action_id in this.actions) {
            var action = this.actions[action_id];

            // Replace placeholders in target
            var real_target = Helper.replacePlaceholdersInURL(action.target, row);

            html.push(
                '',
                    '',
                ''
            );
        }

        return html.join(' ');
    }
}

/**
 * Helper
 */
var Helper =
{
    replacePlaceholdersInURL: function(target, values) {
        var target_parts = target.split('/');

        // Check if we have a dictionary or an array of values
        if(values instanceof Array) {
            var key = 0;
            for(part_index in target_parts) {
                if(target_parts[part_index].indexOf(":") == 0) {
                    if(values[key] !== undefined) {
                        target_parts[part_index] = values[key];
                    } else {
                        console.error('Placeholder is referring to undefined key "' + key + '"');
                    }
                }
            }
        } else {
            for(part_index in target_parts) {
                if(target_parts[part_index].indexOf(":") == 0) {
                    var key = target_parts[part_index].slice(1);
                    if(values[key] !== undefined) {
                        target_parts[part_index] = values[key];
                    } else {
                        console.error('Placeholder is referring to undefined key "' + key + '"');
                    }
                }
            }
        }

        return target_parts.join('/');
    }
}

/**
 * Navigation
 */

var Navigation =
{
    navigateToHome : function() {
        // TODO navigate home...
        console.error("Not implemented yet: Navigation.navigateToHome()");
    },

    navigateToURL : function(url) {
        // Make sure we are navigating locally
        if(!url.indexOf('#') == -1) {
            window.location = url;
        }

        // Extract the target from the URL
        var target = url.split('#')[1];

        if(target.length == 0) {
            Navigation.navigateToHome();
            return;
        }

        // Split the target into model and view
        target = target.split('/')
        if(target.length >= 3) {

            UIComponents.loadingMask($('#main'));

            // Load the view config and handle it
            $.ajax({
              dataType: 'json',
              url: '/backend/modules/' +  target[1] + '/views/' + target[2],
              success: function(data) {
                  UI.applyViewConfig(data, target.slice(3));
              }
            });

        } else {
            console.error('URL "' + url + '" is not a valid target!');
        }
    }
}

/**
 * Stores
 */

 var Stores =
 {
    data : {},

    getStore : function(module_name, store_name) {
        return this.data[module_name + '_' + store_name];
    },

    getValueForStoreAndKey : function(module_name, store_name, key) {
        var store = this.getStore(module_name, store_name);
        return store.data[key];
    },

    load : function(module_name, store_name) {
        $.ajax({
        dataType: "json",
        url: "/backend/modules/"+module_name+'/stores/'+store_name,
        success: function(store) {
            Stores.data[module_name + '_' + store_name] = store;
        }
    });
    }

 }

/**
 * Initialization
 */

// Initialize JS
function init() {
    // Load configuration
    UIComponents.loadingMask($('#sidebar-main-menu'));
    $.ajax({
        dataType: "json",
        url: "/backend/config",
        success: function(config) {
            // Load stores
            if(typeof config.stores !== 'undefined') {
                for(i in config.stores) {
                    var store = config.stores[i];
                    Stores.load(store.module_name, store.name);
                }
            }

            // Apply sidebar
            if(typeof config.sidebar !== 'undefined') {
                UI.applySidebarConfig(config.sidebar);
            }
        }
    });
}

$(document).ready(init);<commit_msg>MD-14: Added support for native browser navigation<commit_after>/**
 * User Interface
 */
var UIComponents =
{
    sidebarDropdown : function(title, items) {
        // Generate dropdown and menu
        var dom_dropdown = $('
' + title + '
');
        var dom_menu = $('

');

        // Generate menu entries
        for(item_id in items) {
            var menu_item = items[item_id];
            var dom_menu_item = $('
' + menu_item.title + '
');

            // Append menu entry
            dom_menu.append(dom_menu_item);
        }

        // Append menu
        dom_dropdown.append(dom_menu);

        return dom_dropdown;
    },

    table : function(title, datasource, columns, target) {

        // Clear the target
        target.html('');

        // Build header
        if(title && title.length != 0) {
            var dom_header = $('
' + title + '
');
            target.append(dom_header);
        }

        // Extract fields
        var fields = new Array;
        for(var column_id in columns) {
            if(columns[column_id]["data_key"] !== undefined
               && columns[column_id]["data_key"] !== null
               && columns[column_id]["data_key"].length !== 0)
                fields.push(columns[column_id]["data_key"]);
        }

        // Group up action columns
        var action_column = {
            'formatter' : Formatter.action,
            'sortable' : false,
            'actions' : []
        };

        // Build column config for table
        var columns_config = new Array();
        for(c_index in columns) {
            var column = columns[c_index];

            // Copy basic values
            var column_config = {
                'field' : column.data_key,
                'title' : column.title,
                'visible' : (column.visible == true ? true : false),
                'sortable' : (column.sortable !== undefined ? column.sortable : true)
            }

            // Apply type to column
            if(!column.type) column.type = 'plain';
            switch(column.type) {
                case 'link' :
                    column_config.target = column.target;
                    column_config.formatter = Formatter.link;
                    break;

                case 'email' :
                    column_config.formatter = Formatter.email;
                    break;

                case 'action' :
                    action_column.actions.push({
                        'target' : column.target,
                        'icon' : column.icon
                    });
                    break;

                case 'int' :
                case 'plain' :
                    break;

                default:
                    console.error('Unsupported column type "' + column.type + '"');
            }

            // Add column to table
            if(column.type !== 'action') {
                columns_config.push(column_config);
            }
        }

        // Add action column
        if(action_column.actions.length > 0) {
            columns_config.push(action_column);
        }

        // Build table
        var dom_table = $('

');
        target.append(dom_table);

        dom_table.bootstrapTable({
            url: datasource,
            columns: columns_config,
            sortable: true,
            pagination: true,
            pageSize: 20,
            sidePagination: 'server',
            search: true,
            queryParams: function(params) {
                params.fields = fields.join();
                return params;
            }
        });
    },

    detail : function(title, datasource, fields, dom_target) {

        // Clear the target
        dom_target.html('');

        // Build header
        if(title && title.length != 0) {
            var dom_header = $('
' + title + '
');
            dom_target.append(dom_header);
        }

        // Generate container for the detail view
        var dl_target = $('

');
        dom_target.append(dl_target);

        // Show loading mask
        UIComponents.loadingMask(dl_target);

        // Send a request for data
        $.ajax({
            dataType: 'json',
            url: datasource,
            success: function(data) {

                // Prepare the definition list
                var html = $('

');

                // Go through all the fields
                for(field_id in fields) {
                    var field = fields[field_id];

                    if(field.visible != true) {
                        continue;
                    }

                    var dt = '';
                    var dd = '-';

                    if(field.title !== undefined
                       && field.title !== null) {
                        dt = field.title;
                    }

                    if(data[field.data_key] !== undefined
                       && data[field.data_key] !== null) {

                        var value = data[field.data_key];
                        if(typeof field.store_module !== 'undefined'
                           && typeof field.store_name !== 'undefined'
                           && field.store_module !== null
                           && field.store_name !== null) {
                            value = Stores.getValueForStoreAndKey(field.store_module, field.store_name, value);
                        }

                        // Apply renderer if needed
                        if(field.type !== null && field.type !== '') {
                            dd = Formatter[field.type].call(field, value, data, null);
                        } else {
                            dd = value;
                        }
                    }

                    html.append($('
' + dt + '

' + dd + '
'));
                }

                dl_target.html(html);
            }
        });
    },

    combined : function(title, params, fields, dom_target) {

        // Clear the target
        dom_target.html('');

        // Build header
        if(title && title.length != 0) {
            var dom_header = $('
' + title + '
');
            dom_target.append(dom_header);
        }

        // Generate container for the combined view
        var combined_target = $('

');
        dom_target.append(combined_target);

        // Show loading mask
        UIComponents.loadingMask(combined_target);

        // Iterate over all components
        for(field_id in fields) {
            var field_dom = $('

');
            combined_target.append(field_dom);

            var field = fields[field_id];

            // Split the target into model and view
            var target = Helper.replacePlaceholdersInURL(field.data_key, params)
            target = target.split('/')
            if(target.length >= 3) {

                // Load the view config and handle it
                var first_component = true;
                $.ajax({
                    dataType: 'json',
                    url: '/backend/modules/' +  target[1] + '/views/' + target[2],
                    view_params: target,
                    field_dom: field_dom,
                    success: function(data) {
                        if(first_component) {
                            first_component = false;
                            combined_target.find('.spinner').remove();
                        }
                        UI.applyViewConfig(data, this.view_params.slice(3), this.field_dom);
                    }
                });

            } else {
                console.error('URL "' + url + '" is not a valid target!');
            }
        }
    },

    loadingMask : function(dom_target) {
        var loading_html = $([
            '
',
                '

',
                '

',
            '
'].join(''));

        dom_target.html(loading_html);
    }
}

var UI =
{
    applyViewConfig : function(config, params, dom_target) {

        // Get the main view if no target was defined
        if(typeof dom_target === 'undefined' || dom_target === null) {
            dom_target = $("#main");
        }

        // Handle the type of the view
        switch(config.type) {
            case 'table':
                var datasource = Helper.replacePlaceholdersInURL(config.datasource, params);
                UIComponents.table(config.title, datasource, config.fields, dom_target);
                break;

            case 'detail':
                var datasource = Helper.replacePlaceholdersInURL(config.datasource, params);
                UIComponents.detail(config.title, datasource, config.fields, dom_target);
                break;

            case 'combined':
                UIComponents.combined(config.title, params, config.fields, dom_target);
                break;

            default:
                console.error('Unsupported view type "' + config.type + '"');
        }
    },

    applySidebarConfig : function(sidebar_config) {
        // Load sidebar items
        var sidebar_main_menu = $("#sidebar-main-menu");
        sidebar_main_menu.html('');

        for(var menu_index in sidebar_config) {
            var menu_item = sidebar_config[menu_index];

            var dom_menu_item = UIComponents.sidebarDropdown(menu_item.title, menu_item.items);

            sidebar_main_menu.append(dom_menu_item);
        }

        // Handle Sidebar clicks
        $(".menu-item").click(function() {
            // Switch active sidebar item
            $("li.active").removeClass("active");
            $(this).parent("li").addClass("active");

            // Load view config
             Navigation.navigateToURL(this.href);
        });
    },
};

var Formatter =
{
    email : function(value, row, index) {
        // In case this gets called for an invisible column
        if(!this.visible) return;

        return '' + value + '';
    },

    link : function(value, row, index) {
        // In case this gets called for an invisible column
        if(!this.visible) return;

        // Replace placeholders in target
        var target_parts = this.target.split('/');
        for(part_index in target_parts) {
            if(target_parts[part_index].indexOf(":") == 0) {
                var key = target_parts[part_index].slice(1);
                if(row[key] !== undefined) {
                    target_parts[part_index] = row[key];
                } else {
                    console.error('Column target is referring to undefined key "' + key + '"');
                }
            }
        }
        return '' + value + '';
    },

    action : function(value, row, index) {
        // In case this gets called for an invisible column
        if(!this.visible) return;

        var html = new Array();

        for(action_id in this.actions) {
            var action = this.actions[action_id];

            // Replace placeholders in target
            var real_target = Helper.replacePlaceholdersInURL(action.target, row);

            html.push(
                '',
                    '',
                ''
            );
        }

        return html.join(' ');
    }
}

/**
 * Helper
 */
var Helper =
{
    replacePlaceholdersInURL: function(target, values) {
        var target_parts = target.split('/');

        // Check if we have a dictionary or an array of values
        if(values instanceof Array) {
            var key = 0;
            for(part_index in target_parts) {
                if(target_parts[part_index].indexOf(":") == 0) {
                    if(values[key] !== undefined) {
                        target_parts[part_index] = values[key];
                    } else {
                        console.error('Placeholder is referring to undefined key "' + key + '"');
                    }
                }
            }
        } else {
            for(part_index in target_parts) {
                if(target_parts[part_index].indexOf(":") == 0) {
                    var key = target_parts[part_index].slice(1);
                    if(values[key] !== undefined) {
                        target_parts[part_index] = values[key];
                    } else {
                        console.error('Placeholder is referring to undefined key "' + key + '"');
                    }
                }
            }
        }

        return target_parts.join('/');
    }
}

/**
 * Navigation
 */

var Navigation =
{
    setupListener: function() {
        window.onhashchange = function() {
            Navigation.navigateToURL(window.location.hash);
        };
    },

    navigateToHome : function() {
        $('#main').html('');
    },

    navigateToURL : function(url) {
        // Make sure we are navigating locally
        if(!url.indexOf('#') == -1) {
            window.location = url;
        }
        if(url.length == 0) {
            Navigation.navigateToHome();
            return;
        }

        // Extract the target from the URL
        var target = url.split('#')[1];

        if(target.length == 0) {
            Navigation.navigateToHome();
            return;
        }

        // Split the target into model and view
        target = target.split('/')
        if(target.length >= 3) {

            UIComponents.loadingMask($('#main'));

            // Load the view config and handle it
            $.ajax({
              dataType: 'json',
              url: '/backend/modules/' +  target[1] + '/views/' + target[2],
              success: function(data) {
                  UI.applyViewConfig(data, target.slice(3));
              }
            });

        } else {
            console.error('URL "' + url + '" is not a valid target!');
        }
    }
}

/**
 * Stores
 */

 var Stores =
 {
    data : {},

    getStore : function(module_name, store_name) {
        return this.data[module_name + '_' + store_name];
    },

    getValueForStoreAndKey : function(module_name, store_name, key) {
        var store = this.getStore(module_name, store_name);
        return store.data[key];
    },

    load : function(module_name, store_name) {
        $.ajax({
        dataType: "json",
        url: "/backend/modules/"+module_name+'/stores/'+store_name,
        success: function(store) {
            Stores.data[module_name + '_' + store_name] = store;
        }
    });
    }

 }

/**
 * Initialization
 */

// Initialize JS
function init() {
    // Navigation support
    Navigation.setupListener();

    // Load configuration
    UIComponents.loadingMask($('#sidebar-main-menu'));
    $.ajax({
        dataType: "json",
        url: "/backend/config",
        success: function(config) {
            // Load stores
            if(typeof config.stores !== 'undefined') {
                for(i in config.stores) {
                    var store = config.stores[i];
                    Stores.load(store.module_name, store.name);
                }
            }

            // Apply sidebar
            if(typeof config.sidebar !== 'undefined') {
                UI.applySidebarConfig(config.sidebar);
            }
        }
    });
}

$(document).ready(init);<|endoftext|>


<commit_before>// Closes the sidebar menu
$("#menu-close").click(function(e) {
  e.preventDefault();
  $("#sidebar-wrapper").toggleClass("active");
});

// Opens the sidebar menu
$("#menu-toggle").click(function(e) {
  e.preventDefault();
  $("#sidebar-wrapper").toggleClass("active");
});

// Scrolls to the selected menu item on the page
$(function() {
  $('a[href*=#]:not([href=#])').click(function() {
    if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') || location.hostname == this.hostname) {

      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
      if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top
        }, 1000);
        return false;
      }
    }
  });
});

// Map scrolling behaviour
$(document).ready(function() {
  $('#map_iframe').addClass('scrolloff');
  $('#map').on('click', function () {
    $('#map_iframe').removeClass('scrolloff');
  });

  $('#map_iframe').mouseleave(function  () {
    $('#map_iframe').addClass('scrolloff');
  });
});

// Timeline behaviour
jQuery(document).ready(function($){
	var $timeline_block = $('.cd-timeline-block');

	//hide timeline blocks which are outside the viewport
	$timeline_block.each(function(){
		if($(this).offset().top > $(window).scrollTop()+$(window).height()*0.75) {
			$(this).find('.cd-timeline-img, .cd-timeline-content').addClass('is-hidden');
		}
	});

	//on scolling, show/animate timeline blocks when enter the viewport
	$(window).on('scroll', function(){
		$timeline_block.each(function(){
			if( $(this).offset().top <= $(window).scrollTop()+$(window).height()*0.75 && $(this).find('.cd-timeline-img').hasClass('is-hidden') ) {
				$(this).find('.cd-timeline-img, .cd-timeline-content').removeClass('is-hidden').addClass('bounce-in');
			}
		});
	});
});

// ICO behaviour

$(document).ready(function () {
    /* The data of our chart */
    var data = {
        1: 3,
        2: 1,
        3: 3,
        4: 2,
        5: 2,
        6: 1,
        7: 3,
        8: 1,
        9: 3,
        10: 2,
        11: 2,
        12: 3,
        13: 1,
        14: 2,
        15: 2
    };
    setDoughnut(data);

    /* Function that fills the doughtnut with our data */
    function setDoughnut(data) {
        for (key in data) {
            var piece = ".piece-" + key;

            var color;
            if (key < 5 || key >= 15) {
                color = "blue";
            } else if (key >= 5 && key < 10) {
                color = "green";
            } else {
                color = "red";
            }

            if (data[key] > 1) {
                $(".doughnuts-in").find(piece).addClass(color + "in");
                if (data[key] >= 2) {
                    $(".doughnuts-mid").find(piece).addClass(color + "mid");
                    if (data[key] == 3) {
                        $(".doughnuts-out").find(piece).addClass(color + "out");
                    } else {
                        $(".doughnuts-out").find(piece).addClass("grey");
                    }
                } else {
                    $(".doughnuts-mid").find(piece).addClass("grey");
                    $(".doughnuts-out").find(piece).addClass("greyout");
                }
            } else {
                $(".doughnuts-in").find(piece).addClass("empty");
                $(".doughnuts-mid").find(piece).addClass("grey");
                $(".doughnuts-out").find(piece).addClass("greyout");
            }
        }
    }

    /* Hovering a piece */
    $(".ounch-logo-pieces").hover(function () {
        var piece = $(this).attr('class').split(' ')[1];
        $("." + piece).darken(30);
    }, function () {
        var piece = $(this).attr('class').split(' ')[1];
        $("." + piece).darken(-44);
    });

    /* Clicking a piece */
    $('.ounch-logo-pieces').click(function () {
        var piece = $(this).attr('class').split(' ')[1];
        var title = $("#labels #" + piece).html();
        $('#dialog').dialog();
        $("#dialog").dialog( "option", "title", title);
        $("#dialog").dialog().siblings('.ui-dialog-titlebar').removeClass('ui-widget-header');
    });

    /* jQuery darkener */
    jQuery.fn.darken = function (darkenPercent) {
        $(this).each(function () {
            var rgb = $(this).css('background-color');
            rgb = rgb.replace('rgb(', '').replace(')', '').split(',');
            var red = $.trim(rgb[0]);
            var green = $.trim(rgb[1]);
            var blue = $.trim(rgb[2]);

            // darken
            red = parseInt(red * (100 - darkenPercent) / 100);
            green = parseInt(green * (100 - darkenPercent) / 100);
            blue = parseInt(blue * (100 - darkenPercent) / 100);
            // lighten
            /* red = parseInt(red * (100 - darkenPercent) / 100);
		green = parseInt(green * (100 - darkenPercent) / 100);
		blue = parseInt(blue * (100 - darkenPercent) / 100); */

            rgb = 'rgb(' + red + ', ' + green + ', ' + blue + ')';

            $(this).css('background-color', rgb);
        });
        return this;
    }
});
<commit_msg>icorevert<commit_after>// Closes the sidebar menu
$("#menu-close").click(function(e) {
  e.preventDefault();
  $("#sidebar-wrapper").toggleClass("active");
});

// Opens the sidebar menu
$("#menu-toggle").click(function(e) {
  e.preventDefault();
  $("#sidebar-wrapper").toggleClass("active");
});

// Scrolls to the selected menu item on the page
$(function() {
  $('a[href*=#]:not([href=#])').click(function() {
    if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') || location.hostname == this.hostname) {

      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
      if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top
        }, 1000);
        return false;
      }
    }
  });
});

// Map scrolling behaviour
$(document).ready(function() {
  $('#map_iframe').addClass('scrolloff');
  $('#map').on('click', function () {
    $('#map_iframe').removeClass('scrolloff');
  });

  $('#map_iframe').mouseleave(function  () {
    $('#map_iframe').addClass('scrolloff');
  });
});

// Timeline behaviour
jQuery(document).ready(function($){
	var $timeline_block = $('.cd-timeline-block');

	//hide timeline blocks which are outside the viewport
	$timeline_block.each(function(){
		if($(this).offset().top > $(window).scrollTop()+$(window).height()*0.75) {
			$(this).find('.cd-timeline-img, .cd-timeline-content').addClass('is-hidden');
		}
	});

	//on scolling, show/animate timeline blocks when enter the viewport
	$(window).on('scroll', function(){
		$timeline_block.each(function(){
			if( $(this).offset().top <= $(window).scrollTop()+$(window).height()*0.75 && $(this).find('.cd-timeline-img').hasClass('is-hidden') ) {
				$(this).find('.cd-timeline-img, .cd-timeline-content').removeClass('is-hidden').addClass('bounce-in');
			}
		});
	});
});

<|endoftext|>


<commit_before>/*
  MIT License http://www.opensource.org/licenses/mit-license.php
  Author Arun Kumar T K @aruntk
  */
import fs from 'fs'
import url from 'url'
import path from 'path'
import vm from 'vm'
import parse5 from 'parse5'
import loaderUtils from 'loader-utils'
import polyclean from 'polyclean'
import * as _ from 'lodash'
import assign from 'object-assign'
import wcRenderer from './renderer'

function randomIdent() {
  return 'xxxWCLINKxxx' + Math.random() + Math.random() + 'xxx'
}

class DissectHtml {
  constructor(config, options) {
    this.dissected = {
      html: '/*__wc__loader*/\n',
      js: '',
      requires: '', // appended first
    }
    this.config = config
    this.links = {}
    this.otherDeps = []
    this.options = options
  }
  dissect(contents, sourcePath) {
    this.path = sourcePath
    const children = contents.childNodes || []
    this.processChildNodes(children)
    // this.dissected.js += `\n${this.dissected.js}\n`
  }
  processChildNodes(childNodes) {
    const self = this
    let pushNodes = []
    const processedNodes = _.compact(_.map(childNodes, child => {
      switch (child.nodeName) {
        case 'head':
        case 'body': {
          const _child = child
          _child.childNodes = self.processChildNodes(_child.childNodes)
          const _childContents = parse5.serialize(_child)
          this.dissected[_child.nodeName] = _childContents
          // boolean where determines the section of html the content goes in
          const where = _child.nodeName === 'head'
          self.dissected.html += `\n${wcRenderer.generateJS(_childContents, where)}\n`
        }
          break

        case 'template': {
          const template = child
          // template does not have a direct childNodes property.
          // instead it has a content peoperty which contains a document fragment node.
          // the document fragment node has childNodes prop
          const tmContent = template.content
          const isWalkable = tmContent && tmContent.nodeName === '#document-fragment' && tmContent.childNodes
          if (isWalkable) {
            tmContent.childNodes = self.processChildNodes(tmContent.childNodes)
          }
          template.content = tmContent
          return template
        }
        case 'link': {
          const processedLinkChild = self.processLinks(child)
          if (processedLinkChild) {
            return processedLinkChild
          }
        }
          break
        case 'script': {
          const result = self.processScripts(child)
          if (result) {
            return result
          }
        }
          break
        case 'style': {
          if (child.childNodes && child.childNodes.length) {
            const childNode = child.childNodes[0]
            const css = childNode.value
            const result = self.processStyle(css)
            if (result) {
              childNode.value = result
            }
          }
          return child
        }
        case 'dom-module': {
          const domModule = child
          if (domModule.childNodes) {
            domModule.childNodes = self.processChildNodes(domModule.childNodes)
          }
          return domModule
        }
        case 'div': {
          // this is required to avoid div added by vulcanization
          const divChild = child
          const attrs = _.filter(divChild.attrs, o => (o.name === 'hidden' || o.name === 'by-vulcanize'))
          if (attrs.length >= 2) {
            const _childNodes = self.processChildNodes(divChild.childNodes)
            pushNodes = pushNodes.concat(_childNodes)
          } else {
            if (divChild.childNodes) {
              divChild.childNodes = self.processChildNodes(divChild.childNodes)
            }
            return divChild
          }
        }
          break
          // remove comment and documentType nodes
        case '#comment':
        case '#documentType':
          break
          // every other node
        default: {
          const defChild = child
          const attrs = _.map(defChild.attrs, o => {
            // all src values without [[*]] and {{*}}
            if (o.name === 'src' || o.name === 'src$') {
              o.value = self._changeRelUrl(o.value)
            }
            return o
          })
          defChild.attrs = attrs
          if (defChild.childNodes) {
            defChild.childNodes = self.processChildNodes(defChild.childNodes)
          }
          return defChild
        }
      }
      return null
    }))
    return processedNodes.concat(pushNodes)
  }
  processStyle(css, cssBasePath = '') {
    return this._changeCssUrls(polyclean.stripCss(css), cssBasePath)
  }
  _changeCssUrls(text, cssBasePath) {
    const self = this
    // to get -> property: url(filepath)

    const processed = text.replace(/url\(['|']?([^)]+?)['|']?\)/ig, function (_u, url) {
      // to get -> filepath from url(filepath), url('filepath') and url('filepath')
      return `url(${self._changeRelUrl(url, path.dirname(cssBasePath))})`
    })
    return processed
  }

  processScripts(child) {
    const self = this
    const importSource = _.find(child.attrs, v => (v.name === 'src'))
    if (importSource && importSource.value) {
      // script tag contains a source file url
      const importableUrl = self.importableUrl(importSource.value)
      if (!importableUrl) {
        // link is absolute or remote. so do nothing
        return child
      }
      self.dissected.requires += `\nrequire('${importableUrl}');\n`
    } else {
      // script inside the tag is added to main js part
      self.dissected.js += `\n${parse5.serialize(child)}\n`
    }
    return null
  }
  _changeRelUrl(inpUrl, basePath) {
    // avoids var(--url-variable) and bound properties [[prop]] and {{prop}}
    if (inpUrl && !inpUrl.match(/var\(.*?\)|({{|\[\[)\s*[\w\.]+\s*(}}|\]\])/ig)) {

      const p = basePath ? path.join('', basePath, inpUrl) : inpUrl
      // avoids absolute & remote urls
      const link = this.importableUrl(p)
      if (link) {
        do {
          var ident = randomIdent()
        } while (this.links[ident])
        this.links[ident] = link
        return ident
      }
    }
    return inpUrl
  }
  // changes relative urls to request format and returns if link is absolute.
  importableUrl(link) {
    const root = this.config.root
    if (!loaderUtils.isUrlRequest(link, root)) {
      return
    }
    const uri = url.parse(link)
    if (uri.hash !== null && uri.hash !== undefined) {
      uri.hash = null
      link = uri.format()
    }

    return loaderUtils.urlToRequest(link, root)
  }
  processLinks(child) {
    const self = this
    // <link rel='import'...> and <link rel='stylesheet'...>
    const supportedRels = ['import', 'stylesheet']
    const ifImport = _.find(child.attrs, v => (v.name === 'rel' && supportedRels.indexOf(v.value) > -1))
    if (ifImport) {
      const hrefAttr = _.find(child.attrs, v => v.name === 'href')
      if (hrefAttr && hrefAttr.value) {
        const link = self.importableUrl(hrefAttr.value) || hrefAttr.value
        switch (ifImport.value) {
          case 'import': {
            // file is imported using require
            if (!link) {
              return child
            }
            const typeAttr = _.find(child.attrs, v => (v.name === 'type'))
            if (typeAttr) {
              // process type="css" files
              switch (typeAttr.value) {
                case 'css':
                  return self.processCssImport(link, child)
                default:
                  break
              }
            }
            const importable = `require('${link}');`
            self.dissected.requires += `\n${importable}\n`
          }
            break
            // Processing <link rel='stylesheet' href='filename.css'>
          case 'stylesheet':
            // absolute file path
            return self.processCssImport(link, child)
          default:
            break
        }
      } else {
        return child
      }
    } else {
      return child
    }
    return null
  }
  processCssImport(link, child) {
    const absPath = path.resolve(path.dirname(this.path), link)
    this.otherDeps.push(absPath)
    // checks if file exists
    if (fs.existsSync(absPath)) {
      const contents = fs.readFileSync(absPath, 'utf8')
      // css is inlined
      const minified = this.processStyle(contents, link)
      if (minified) {
        // link tag is replaced with style tag
        return _.extend(child, {
          nodeName: 'style',
          tagName: 'style',
          attrs: [],
          childNodes: [
            {
              nodeName: '#text',
              value: minified
            }
          ]
        })
      }
    }
    return child
  }
}
function getLoaderConfig(context) {
  const query = loaderUtils.parseQuery(context.query)
  const configKey = query.config || 'wcLoader'
  const config = context.options && context.options.hasOwnProperty(configKey) ? context.options[configKey] : {}

  delete query.config

  return assign(query, config)
}
function convertPlaceholder(html, links, config) {
  const callback = this.async()
  const publicPath = typeof config.publicPath !== 'undefined' ? config.publicPath : this.options.output.publicPath
  const phs = Object.keys(links) // placeholders
  Promise.all(phs.map(function loadModule(ph) {
    const resourcePath = links[ph]
    const absPath = path.resolve(path.dirname(this.resourcePath), resourcePath)
    this.addDependency(absPath)
    return new Promise((resolve, reject) => {
      this.loadModule(resourcePath, (err, src) => err ? reject(err) : resolve(src))
    })
  }, this))
    .then(sources => sources.map(
      // runModule may throw an error, so it's important that our promise is rejected in this case
      (src, i) => runModule(src, links[phs[i]], publicPath)
    ))
    .then(results => {
      return html.replace(/xxxWCLINKxxx[0-9\.]+xxx/g, function (match) {
        const i = phs.indexOf(match)
        if (i === -1) {
          return match
        }
        return results[i]
      })
    })
    .then(content => callback(null, content))
    .catch(callback)
}

function runModule(src, filename, publicPath = '') {
  const script = new vm.Script(src, {
    filename,
    displayErrors: true
  })
  const sandbox = {
    module: {},
    __webpack_public_path__: publicPath // eslint-disable-line camelcase
  }

  script.runInNewContext(sandbox)
  return sandbox.module.exports.toString()
}
module.exports = function (source) {
  if (this.cacheable) {
    this.cacheable()
  }
  const config = getLoaderConfig(this)
  const srcFilepath = this.resourcePath
  const parsed = parse5.parse(source)
  const dissectFn = new DissectHtml(config, this.options)
  dissectFn.dissect(parsed, srcFilepath)
  const links = dissectFn.links
  const inject = dissectFn.dissected.html + dissectFn.dissected.requires + dissectFn.dissected.js
  // otherDeps -> css dependencies for hot code reload.
  dissectFn.otherDeps.forEach(dep => {
    this.addDependency(dep)
  }, this)
  convertPlaceholder.call(this, inject, links, config)
}
<commit_msg>Parse double quotes in urls in css as well<commit_after>/*
  MIT License http://www.opensource.org/licenses/mit-license.php
  Author Arun Kumar T K @aruntk
  */
import fs from 'fs'
import url from 'url'
import path from 'path'
import vm from 'vm'
import parse5 from 'parse5'
import loaderUtils from 'loader-utils'
import polyclean from 'polyclean'
import * as _ from 'lodash'
import assign from 'object-assign'
import wcRenderer from './renderer'

function randomIdent() {
  return 'xxxWCLINKxxx' + Math.random() + Math.random() + 'xxx'
}

class DissectHtml {
  constructor(config, options) {
    this.dissected = {
      html: '/*__wc__loader*/\n',
      js: '',
      requires: '', // appended first
    }
    this.config = config
    this.links = {}
    this.otherDeps = []
    this.options = options
  }
  dissect(contents, sourcePath) {
    this.path = sourcePath
    const children = contents.childNodes || []
    this.processChildNodes(children)
    // this.dissected.js += `\n${this.dissected.js}\n`
  }
  processChildNodes(childNodes) {
    const self = this
    let pushNodes = []
    const processedNodes = _.compact(_.map(childNodes, child => {
      switch (child.nodeName) {
        case 'head':
        case 'body': {
          const _child = child
          _child.childNodes = self.processChildNodes(_child.childNodes)
          const _childContents = parse5.serialize(_child)
          this.dissected[_child.nodeName] = _childContents
          // boolean where determines the section of html the content goes in
          const where = _child.nodeName === 'head'
          self.dissected.html += `\n${wcRenderer.generateJS(_childContents, where)}\n`
        }
          break

        case 'template': {
          const template = child
          // template does not have a direct childNodes property.
          // instead it has a content peoperty which contains a document fragment node.
          // the document fragment node has childNodes prop
          const tmContent = template.content
          const isWalkable = tmContent && tmContent.nodeName === '#document-fragment' && tmContent.childNodes
          if (isWalkable) {
            tmContent.childNodes = self.processChildNodes(tmContent.childNodes)
          }
          template.content = tmContent
          return template
        }
        case 'link': {
          const processedLinkChild = self.processLinks(child)
          if (processedLinkChild) {
            return processedLinkChild
          }
        }
          break
        case 'script': {
          const result = self.processScripts(child)
          if (result) {
            return result
          }
        }
          break
        case 'style': {
          if (child.childNodes && child.childNodes.length) {
            const childNode = child.childNodes[0]
            const css = childNode.value
            const result = self.processStyle(css)
            if (result) {
              childNode.value = result
            }
          }
          return child
        }
        case 'dom-module': {
          const domModule = child
          if (domModule.childNodes) {
            domModule.childNodes = self.processChildNodes(domModule.childNodes)
          }
          return domModule
        }
        case 'div': {
          // this is required to avoid div added by vulcanization
          const divChild = child
          const attrs = _.filter(divChild.attrs, o => (o.name === 'hidden' || o.name === 'by-vulcanize'))
          if (attrs.length >= 2) {
            const _childNodes = self.processChildNodes(divChild.childNodes)
            pushNodes = pushNodes.concat(_childNodes)
          } else {
            if (divChild.childNodes) {
              divChild.childNodes = self.processChildNodes(divChild.childNodes)
            }
            return divChild
          }
        }
          break
          // remove comment and documentType nodes
        case '#comment':
        case '#documentType':
          break
          // every other node
        default: {
          const defChild = child
          const attrs = _.map(defChild.attrs, o => {
            // all src values without [[*]] and {{*}}
            if (o.name === 'src' || o.name === 'src$') {
              o.value = self._changeRelUrl(o.value)
            }
            return o
          })
          defChild.attrs = attrs
          if (defChild.childNodes) {
            defChild.childNodes = self.processChildNodes(defChild.childNodes)
          }
          return defChild
        }
      }
      return null
    }))
    return processedNodes.concat(pushNodes)
  }
  processStyle(css, cssBasePath = '') {
    return this._changeCssUrls(polyclean.stripCss(css), cssBasePath)
  }
  _changeCssUrls(text, cssBasePath) {
    const self = this
    // to get -> property: url(filepath)

    const processed = text.replace(/url\(["'|]?([^"'|)]+?)["'|]?\)/ig, function (_u, url) {
      // to get -> filepath from url(filepath), url('filepath') and url('filepath')
      return `url(${self._changeRelUrl(url, path.dirname(cssBasePath))})`
    })
    return processed
  }

  processScripts(child) {
    const self = this
    const importSource = _.find(child.attrs, v => (v.name === 'src'))
    if (importSource && importSource.value) {
      // script tag contains a source file url
      const importableUrl = self.importableUrl(importSource.value)
      if (!importableUrl) {
        // link is absolute or remote. so do nothing
        return child
      }
      self.dissected.requires += `\nrequire('${importableUrl}');\n`
    } else {
      // script inside the tag is added to main js part
      self.dissected.js += `\n${parse5.serialize(child)}\n`
    }
    return null
  }
  _changeRelUrl(inpUrl, basePath) {
    // avoids var(--url-variable) and bound properties [[prop]] and {{prop}}
    if (inpUrl && !inpUrl.match(/var\(.*?\)|({{|\[\[)\s*[\w\.]+\s*(}}|\]\])/ig)) {

      const p = basePath ? path.join('', basePath, inpUrl) : inpUrl
      // avoids absolute & remote urls
      const link = this.importableUrl(p)
      if (link) {
        do {
          var ident = randomIdent()
        } while (this.links[ident])
        this.links[ident] = link
        return ident
      }
    }
    return inpUrl
  }
  // changes relative urls to request format and returns if link is absolute.
  importableUrl(link) {
    const root = this.config.root
    if (!loaderUtils.isUrlRequest(link, root)) {
      return
    }
    const uri = url.parse(link)
    if (uri.hash !== null && uri.hash !== undefined) {
      uri.hash = null
      link = uri.format()
    }

    return loaderUtils.urlToRequest(link, root)
  }
  processLinks(child) {
    const self = this
    // <link rel='import'...> and <link rel='stylesheet'...>
    const supportedRels = ['import', 'stylesheet']
    const ifImport = _.find(child.attrs, v => (v.name === 'rel' && supportedRels.indexOf(v.value) > -1))
    if (ifImport) {
      const hrefAttr = _.find(child.attrs, v => v.name === 'href')
      if (hrefAttr && hrefAttr.value) {
        const link = self.importableUrl(hrefAttr.value) || hrefAttr.value
        switch (ifImport.value) {
          case 'import': {
            // file is imported using require
            if (!link) {
              return child
            }
            const typeAttr = _.find(child.attrs, v => (v.name === 'type'))
            if (typeAttr) {
              // process type="css" files
              switch (typeAttr.value) {
                case 'css':
                  return self.processCssImport(link, child)
                default:
                  break
              }
            }
            const importable = `require('${link}');`
            self.dissected.requires += `\n${importable}\n`
          }
            break
            // Processing <link rel='stylesheet' href='filename.css'>
          case 'stylesheet':
            // absolute file path
            return self.processCssImport(link, child)
          default:
            break
        }
      } else {
        return child
      }
    } else {
      return child
    }
    return null
  }
  processCssImport(link, child) {
    const absPath = path.resolve(path.dirname(this.path), link)
    this.otherDeps.push(absPath)
    // checks if file exists
    if (fs.existsSync(absPath)) {
      const contents = fs.readFileSync(absPath, 'utf8')
      // css is inlined
      const minified = this.processStyle(contents, link)
      if (minified) {
        // link tag is replaced with style tag
        return _.extend(child, {
          nodeName: 'style',
          tagName: 'style',
          attrs: [],
          childNodes: [
            {
              nodeName: '#text',
              value: minified
            }
          ]
        })
      }
    }
    return child
  }
}
function getLoaderConfig(context) {
  const query = loaderUtils.parseQuery(context.query)
  const configKey = query.config || 'wcLoader'
  const config = context.options && context.options.hasOwnProperty(configKey) ? context.options[configKey] : {}

  delete query.config

  return assign(query, config)
}
function convertPlaceholder(html, links, config) {
  const callback = this.async()
  const publicPath = typeof config.publicPath !== 'undefined' ? config.publicPath : this.options.output.publicPath
  const phs = Object.keys(links) // placeholders
  Promise.all(phs.map(function loadModule(ph) {
    const resourcePath = links[ph]
    const absPath = path.resolve(path.dirname(this.resourcePath), resourcePath)
    this.addDependency(absPath)
    return new Promise((resolve, reject) => {
      this.loadModule(resourcePath, (err, src) => err ? reject(err) : resolve(src))
    })
  }, this))
    .then(sources => sources.map(
      // runModule may throw an error, so it's important that our promise is rejected in this case
      (src, i) => runModule(src, links[phs[i]], publicPath)
    ))
    .then(results => {
      return html.replace(/xxxWCLINKxxx[0-9\.]+xxx/g, function (match) {
        const i = phs.indexOf(match)
        if (i === -1) {
          return match
        }
        return results[i]
      })
    })
    .then(content => callback(null, content))
    .catch(callback)
}

function runModule(src, filename, publicPath = '') {
  const script = new vm.Script(src, {
    filename,
    displayErrors: true
  })
  const sandbox = {
    module: {},
    __webpack_public_path__: publicPath // eslint-disable-line camelcase
  }

  script.runInNewContext(sandbox)
  return sandbox.module.exports.toString()
}
module.exports = function (source) {
  if (this.cacheable) {
    this.cacheable()
  }
  const config = getLoaderConfig(this)
  const srcFilepath = this.resourcePath
  const parsed = parse5.parse(source)
  const dissectFn = new DissectHtml(config, this.options)
  dissectFn.dissect(parsed, srcFilepath)
  const links = dissectFn.links
  const inject = dissectFn.dissected.html + dissectFn.dissected.requires + dissectFn.dissected.js
  // otherDeps -> css dependencies for hot code reload.
  dissectFn.otherDeps.forEach(dep => {
    this.addDependency(dep)
  }, this)
  convertPlaceholder.call(this, inject, links, config)
}
<|endoftext|>


<commit_before>/*!
 * Custom Code file for kraftychocolates
 */

function show_callus_modal() {
  console.log("Callus modal shown");
  return false;
}

 $( window ).resize(function() {
  if($(window).width() <=768) {
    $('.callus').addClass("callus-popup");
  }
  else {
    $('.callus').removeClass("callus-popup");
  }
});

$(".callus-popup").click(show_callus_modal);
<commit_msg>Update custom.js<commit_after>/*!
 * Custom Code file for kraftychocolates
 */

function show_callus_modal() {
  console.log("Callus modal shown");
  return false;
}

function callus_switcher = function() {
  if($(window).width() <=768) {
    $('.callus').addClass("callus-popup");
    $(".callus-popup").on("click",show_callus_modal);
  }
  else {
    if($(".callus-popup").length){
      $(".callus-popup").off("click");
      $('.callus').removeClass("callus-popup");
    }
  }
}

$(document).ready(callus_switcher);
$( window ).resize(callus_switcher);

<|endoftext|>


<commit_before>import { MemoryStorage, WebStorage } from './storage';

// eslint-disable-next-line
const _global = (typeof window !== 'undefined' ? window : global || {});

/**
 * @type {{install: (function(Object, Object): WebStorage)}}
 */
const VueStorage = {
  /**
   * Install plugin
   *
   * @param {Object} Vue
   * @param {Object} options
   * @returns {WebStorage}
   */
  install(Vue, options = {}) {
    const _options = Object.assign({}, options, {
      storage: options.storage || 'local',
      name: options.name || 'ls',
    });

    if (_options.storage && ['memory', 'local', 'session'].indexOf(_options.storage) === -1) {
      throw new Error(`Vue-ls: Storage "${_options.storage}" is not supported`);
    }

    let store = null;

    switch(_options.storage) { // eslint-disable-line
      case 'local':
        store = 'localStorage' in _global
          ? _global.localStorage
          : null
        ;
        break;

      case 'session':
        store = 'sessionStorage' in _global
          ? _global.sessionStorage
          : null
        ;
        break;
      case 'memory': store = MemoryStorage;
        break;
    }

    if (!store) {
      store = MemoryStorage;
      // eslint-disable-next-line
      console.error(`Vue-ls: Storage "${_options.storage}" is not supported your system, use memory storage`);
    }

    const ls = new WebStorage(store);

    ls.setOptions(Object.assign(ls.options, {
      namespace: '',
    }, _options || {}));

    Vue[_options.name] = ls; // eslint-disable-line
    Object.defineProperty(Vue.prototype, `$${_options.name}`, {
      /**
       * Define $ls property
       *
       * @return {WebStorage}
       */
      get() {
        return ls;
      },
    });
  },
};

_global.VueStorage = VueStorage;

export default VueStorage;
<commit_msg>move case content in a new line<commit_after>import { MemoryStorage, WebStorage } from './storage';

// eslint-disable-next-line
const _global = (typeof window !== 'undefined' ? window : global || {});

/**
 * @type {{install: (function(Object, Object): WebStorage)}}
 */
const VueStorage = {
  /**
   * Install plugin
   *
   * @param {Object} Vue
   * @param {Object} options
   * @returns {WebStorage}
   */
  install(Vue, options = {}) {
    const _options = Object.assign({}, options, {
      storage: options.storage || 'local',
      name: options.name || 'ls',
    });

    if (_options.storage && ['memory', 'local', 'session'].indexOf(_options.storage) === -1) {
      throw new Error(`Vue-ls: Storage "${_options.storage}" is not supported`);
    }

    let store = null;

    switch(_options.storage) { // eslint-disable-line
      case 'local':
        store = 'localStorage' in _global
          ? _global.localStorage
          : null
        ;
        break;

      case 'session':
        store = 'sessionStorage' in _global
          ? _global.sessionStorage
          : null
        ;
        break;
      case 'memory':
        store = MemoryStorage;
        break;
    }

    if (!store) {
      store = MemoryStorage;
      // eslint-disable-next-line
      console.error(`Vue-ls: Storage "${_options.storage}" is not supported your system, use memory storage`);
    }

    const ls = new WebStorage(store);

    ls.setOptions(Object.assign(ls.options, {
      namespace: '',
    }, _options || {}));

    Vue[_options.name] = ls; // eslint-disable-line
    Object.defineProperty(Vue.prototype, `$${_options.name}`, {
      /**
       * Define $ls property
       *
       * @return {WebStorage}
       */
      get() {
        return ls;
      },
    });
  },
};

_global.VueStorage = VueStorage;

export default VueStorage;
<|endoftext|>


<commit_before>const {
  dirname,
  isAbsolute,
  join,
  parse,
} = require('path');
const EventEmitter = require('events');
const changeCase = require('change-case');
const pathBuilder = require('./path-builder');
const pipeline = require('./pipeline');

require('babel-core/register')({
    presets: ['react']
});

const idyll = (options = {}, cb) => {
  const opts = Object.assign({}, {
      watch: false,
      datasets: 'data',
      minify: true,
      components: 'components',
      defaultComponents: join(
        __dirname,
        '..',
        'node_modules',
        'idyll-default-components'
      ),
      layout: 'blog',
      output: 'build',
      template: join(
        __dirname,
        'client',
        '_index.html'
      ),
      theme: 'idyll',
      transform: [],
      compilerOptions: {
        spellcheck: true
      },
    },
    options
  );
  if (opts.watch) opts.minify = false; // speed!

  const paths = pathBuilder(opts);

  const inputPackage = require(paths.PACKAGE_FILE);
  const inputConfig = Object.assign({
    components: {},
    transform: []
  }, inputPackage.idyll || {});
  for (let key in inputConfig.components) {
    inputConfig.components[changeCase.paramCase(key)] = inputConfig.components[key];
    delete inputConfig.components[key];
  };

  // Handle options that can be provided via options or via package.json
  opts.transform = options.transform || inputConfig.transform || opts.transform;

  let bs;

  class IdyllInstance extends EventEmitter {
    build(src) {
      if (src) opts.inputString = src;
      if (opts.debug) console.time('Build Time');

      pipeline.build(opts, paths, inputConfig)
        .then((output) => {
          if (opts.debug) console.timeEnd('Build Time')
          this.emit('update', output);
        })
        .then(() => {
          if (!bs && opts.watch && opts.inputFile) {
            bs = require('browser-sync').create();
            // any time an input files changes we will recompile .idl source
            // and write ast.json, components.js, and data.js to disk
            bs.watch(paths.COMPONENTS_DIR, {ignoreInitial: true}, inst.build);
            bs.watch(paths.DEFAULT_COMPONENTS_DIR, {ignoreInitial: true}, inst.build);
            bs.watch(paths.IDYLL_INPUT_FILE, {ignoreInitial: true}, inst.build);
            // that will cause watchify to rebuild so we just watch the output bundle file
            // and reload when it is updated. Watch options are to prevent multiple change
            // events since the bundle file can be somewhat large
            bs.watch(paths.JS_OUTPUT_FILE, {awaitWriteFinish: {stabilityThreshold: 499}}, bs.reload);
            // when CSS changes we reassemble and inject it
            bs.watch(paths.CSS_INPUT_FILE, {ignoreInitial: true}, () => {
              pipeline.updateCSS(opts, paths).then(() => {
                bs.reload('styles.css')
              });
            });

            bs.init({
              cors: true,
              logLevel: 'warn',
              logPrefix: 'Idyll',
              notify: false,
              server: [paths.OUTPUT_DIR, paths.INPUT_DIR],
              ui: false
            });
          }
        })
        .catch(console.error.bind(console));
      return this;
    }
  }

  const inst = new IdyllInstance();

  return inst;
};

module.exports = idyll;
<commit_msg>Make sure package.json exists<commit_after>const fs = require('fs');
const {
  dirname,
  isAbsolute,
  join,
  parse,
} = require('path');
const EventEmitter = require('events');
const changeCase = require('change-case');
const pathBuilder = require('./path-builder');
const pipeline = require('./pipeline');

require('babel-core/register')({
    presets: ['react']
});

const idyll = (options = {}, cb) => {
  const opts = Object.assign({}, {
      watch: false,
      datasets: 'data',
      minify: true,
      components: 'components',
      defaultComponents: join(
        __dirname,
        '..',
        'node_modules',
        'idyll-default-components'
      ),
      layout: 'blog',
      output: 'build',
      template: join(
        __dirname,
        'client',
        '_index.html'
      ),
      theme: 'idyll',
      transform: [],
      compilerOptions: {
        spellcheck: true
      },
    },
    options
  );
  if (opts.watch) opts.minify = false; // speed!

  const paths = pathBuilder(opts);

  const inputPackage = fs.existsSync(paths.PACKAGE_FILE) ? require(paths.PACKAGE_FILE) : {};
  const inputConfig = Object.assign({
    components: {},
    transform: []
  }, inputPackage.idyll || {});
  for (let key in inputConfig.components) {
    inputConfig.components[changeCase.paramCase(key)] = inputConfig.components[key];
    delete inputConfig.components[key];
  };

  // Handle options that can be provided via options or via package.json
  opts.transform = options.transform || inputConfig.transform || opts.transform;

  let bs;

  class IdyllInstance extends EventEmitter {
    build(src) {
      if (src) opts.inputString = src;
      if (opts.debug) console.time('Build Time');

      pipeline.build(opts, paths, inputConfig)
        .then((output) => {
          if (opts.debug) console.timeEnd('Build Time')
          this.emit('update', output);
        })
        .then(() => {
          if (!bs && opts.watch && opts.inputFile) {
            bs = require('browser-sync').create();
            // any time an input files changes we will recompile .idl source
            // and write ast.json, components.js, and data.js to disk
            bs.watch(paths.COMPONENTS_DIR, {ignoreInitial: true}, inst.build);
            bs.watch(paths.DEFAULT_COMPONENTS_DIR, {ignoreInitial: true}, inst.build);
            bs.watch(paths.IDYLL_INPUT_FILE, {ignoreInitial: true}, inst.build);
            // that will cause watchify to rebuild so we just watch the output bundle file
            // and reload when it is updated. Watch options are to prevent multiple change
            // events since the bundle file can be somewhat large
            bs.watch(paths.JS_OUTPUT_FILE, {awaitWriteFinish: {stabilityThreshold: 499}}, bs.reload);
            // when CSS changes we reassemble and inject it
            bs.watch(paths.CSS_INPUT_FILE, {ignoreInitial: true}, () => {
              pipeline.updateCSS(opts, paths).then(() => {
                bs.reload('styles.css')
              });
            });

            bs.init({
              cors: true,
              logLevel: 'warn',
              logPrefix: 'Idyll',
              notify: false,
              server: [paths.OUTPUT_DIR, paths.INPUT_DIR],
              ui: false
            });
          }
        })
        .catch(console.error.bind(console));
      return this;
    }
  }

  const inst = new IdyllInstance();

  return inst;
};

module.exports = idyll;
<|endoftext|>