<commit_before>var torrentStream = require('torrent-stream')
var http = require('http')
var fs = require('fs')
var rangeParser = require('range-parser')
var xtend = require('xtend')
var url = require('url')
var mime = require('mime')
var pump = require('pump')

var parseBlocklist = function (filename) {
  // TODO: support gzipped files
  var blocklistData = fs.readFileSync(filename, { encoding: 'utf8' })
  var blocklist = []
  blocklistData.split('\n').forEach(function (line) {
    var match = null
    if ((match = /^\s*[^#].*?\s*:\s*([a-f0-9.:]+?)\s*-\s*([a-f0-9.:]+?)\s*$/.exec(line))) {
      blocklist.push({
        start: match[1],
        end: match[2]
      })
    }
  })
  return blocklist
}

var truthy = function () {
  return true
}

var createServer = function (e, opts) {
  var server = http.createServer()
  var index = opts.index
  var getType = opts.type || mime.lookup.bind(mime)
  var filter = opts.filter || truthy

  var onready = function () {
    if (typeof index !== 'number') {
      index = e.files.reduce(function (a, b) {
        return a.length > b.length ? a : b
      })
      index = e.files.indexOf(index)
    }

    e.files[index].select()
    server.index = e.files[index]

    if (opts.sort) e.files.sort(opts.sort)
  }

  if (e.torrent) onready()
  else e.on('ready', onready)

  server.on('request', function (request, response) {
    var u = url.parse(request.url)
    var host = request.headers.host || 'localhost'

    var toPlaylist = function () {
      var toEntry = function (file, i) {
        return '#EXTINF:-1,' + file.path + '\n' + 'http://' + host + '/' + i
      }

      return '#EXTM3U\n' + e.files.filter(filter).map(toEntry).join('\n')
    }

    var toJSON = function () {
      var totalPeers = e.swarm.wires

      var activePeers = totalPeers.filter(function (wire) {
        return !wire.peerChoking
      })

      var totalLength = e.files.reduce(function (prevFileLength, currFile) {
        return prevFileLength + currFile.length
      }, 0)

      var toEntry = function (file, i) {
        return {
          name: file.name,
          url: 'http://' + host + '/' + i,
          length: file.length
        }
      }

      var swarmStats = {
        totalLength: totalLength,
        downloaded: e.swarm.downloaded,
        uploaded: e.swarm.uploaded,
        downloadSpeed: parseInt(e.swarm.downloadSpeed(), 10),
        uploadSpeed: parseInt(e.swarm.uploadSpeed(), 10),
        totalPeers: totalPeers.length,
        activePeers: activePeers.length,
        files: e.files.filter(filter).map(toEntry)
      }

      return JSON.stringify(swarmStats, null, '  ')
    }

    // Allow CORS requests to specify arbitrary headers, e.g. 'Range',
    // by responding to the OPTIONS preflight request with the specified
    // origin and requested headers.
    if (request.method === 'OPTIONS' && request.headers['access-control-request-headers']) {
      response.setHeader('Access-Control-Allow-Origin', request.headers.origin)
      response.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
      response.setHeader(
          'Access-Control-Allow-Headers',
          request.headers['access-control-request-headers'])
      response.setHeader('Access-Control-Max-Age', '1728000')

      response.end()
      return
    }

    if (request.headers.origin) response.setHeader('Access-Control-Allow-Origin', request.headers.origin)
    if (u.pathname === '/') u.pathname = '/' + index

    if (u.pathname === '/favicon.ico') {
      response.statusCode = 404
      response.end()
      return
    }

    if (u.pathname === '/.json') {
      var json = toJSON()
      response.setHeader('Content-Type', 'application/json; charset=utf-8')
      response.setHeader('Content-Length', Buffer.byteLength(json))
      response.end(json)
      return
    }

    if (u.pathname === '/.m3u') {
      var playlist = toPlaylist()
      response.setHeader('Content-Type', 'application/x-mpegurl; charset=utf-8')
      response.setHeader('Content-Length', Buffer.byteLength(playlist))
      response.end(playlist)
      return
    }

    e.files.forEach(function (file, i) {
      if (u.pathname.slice(1) === file.name) u.pathname = '/' + i
    })

    var i = Number(u.pathname.slice(1))

    if (isNaN(i) || i >= e.files.length) {
      response.statusCode = 404
      response.end()
      return
    }

    var file = e.files[i]
    var range = request.headers.range
    range = range && rangeParser(file.length, range)[0]
    response.setHeader('Accept-Ranges', 'bytes')
    response.setHeader('Content-Type', getType(file.name))
    response.setHeader('transferMode.dlna.org', 'Streaming')
    response.setHeader('contentFeatures.dlna.org', 'DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=017000 00000000000000000000000000')
    if (!range) {
      response.setHeader('Content-Length', file.length)
      if (request.method === 'HEAD') return response.end()
      pump(file.createReadStream(), response)
      return
    }

    response.statusCode = 206
    response.setHeader('Content-Length', range.end - range.start + 1)
    response.setHeader('Content-Range', 'bytes ' + range.start + '-' + range.end + '/' + file.length)
    response.setHeader('transferMode.dlna.org', 'Streaming')
    response.setHeader('contentFeatures.dlna.org', 'DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=017000 00000000000000000000000000')
    if (request.method === 'HEAD') return response.end()
    pump(file.createReadStream(range), response)
  })

  server.on('connection', function (socket) {
    socket.setTimeout(36000000)
  })

  return server
}

module.exports = function (torrent, opts) {
  if (!opts) opts = {}

  // Parse blocklist
  if (opts.blocklist) opts.blocklist = parseBlocklist(opts.blocklist)

  var engine = torrentStream(torrent, xtend(opts, {port: opts.peerPort}))

  // Just want torrent-stream to list files.
  if (opts.list) return engine

  // Pause/Resume downloading as needed
  engine.on('uninterested', function () {
    engine.swarm.pause()
  })

  engine.on('interested', function () {
    engine.swarm.resume()
  })

  engine.server = createServer(engine, opts)

  // Listen when torrent-stream is ready, by default a random port.
  engine.on('ready', function () {
    engine.server.listen(opts.port || 0, opts.hostname)
  })

  engine.listen()

  return engine
}
<commit_msg>Fixes Reconnecting to Wires<commit_after>var torrentStream = require('torrent-stream')
var http = require('http')
var fs = require('fs')
var rangeParser = require('range-parser')
var xtend = require('xtend')
var url = require('url')
var mime = require('mime')
var pump = require('pump')

var parseBlocklist = function (filename) {
  // TODO: support gzipped files
  var blocklistData = fs.readFileSync(filename, { encoding: 'utf8' })
  var blocklist = []
  blocklistData.split('\n').forEach(function (line) {
    var match = null
    if ((match = /^\s*[^#].*?\s*:\s*([a-f0-9.:]+?)\s*-\s*([a-f0-9.:]+?)\s*$/.exec(line))) {
      blocklist.push({
        start: match[1],
        end: match[2]
      })
    }
  })
  return blocklist
}

var truthy = function () {
  return true
}

var createServer = function (e, opts) {
  var server = http.createServer()
  var index = opts.index
  var getType = opts.type || mime.lookup.bind(mime)
  var filter = opts.filter || truthy

  var onready = function () {
    if (typeof index !== 'number') {
      index = e.files.reduce(function (a, b) {
        return a.length > b.length ? a : b
      })
      index = e.files.indexOf(index)
    }

    e.files[index].select()
    server.index = e.files[index]

    if (opts.sort) e.files.sort(opts.sort)
  }

  if (e.torrent) onready()
  else e.on('ready', onready)

  server.on('request', function (request, response) {
    var u = url.parse(request.url)
    var host = request.headers.host || 'localhost'

    var toPlaylist = function () {
      var toEntry = function (file, i) {
        return '#EXTINF:-1,' + file.path + '\n' + 'http://' + host + '/' + i
      }

      return '#EXTM3U\n' + e.files.filter(filter).map(toEntry).join('\n')
    }

    var toJSON = function () {
      var totalPeers = e.swarm.wires

      var activePeers = totalPeers.filter(function (wire) {
        return !wire.peerChoking
      })

      var totalLength = e.files.reduce(function (prevFileLength, currFile) {
        return prevFileLength + currFile.length
      }, 0)

      var toEntry = function (file, i) {
        return {
          name: file.name,
          url: 'http://' + host + '/' + i,
          length: file.length
        }
      }

      var swarmStats = {
        totalLength: totalLength,
        downloaded: e.swarm.downloaded,
        uploaded: e.swarm.uploaded,
        downloadSpeed: parseInt(e.swarm.downloadSpeed(), 10),
        uploadSpeed: parseInt(e.swarm.uploadSpeed(), 10),
        totalPeers: totalPeers.length,
        activePeers: activePeers.length,
        files: e.files.filter(filter).map(toEntry)
      }

      return JSON.stringify(swarmStats, null, '  ')
    }

    // Allow CORS requests to specify arbitrary headers, e.g. 'Range',
    // by responding to the OPTIONS preflight request with the specified
    // origin and requested headers.
    if (request.method === 'OPTIONS' && request.headers['access-control-request-headers']) {
      response.setHeader('Access-Control-Allow-Origin', request.headers.origin)
      response.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
      response.setHeader(
          'Access-Control-Allow-Headers',
          request.headers['access-control-request-headers'])
      response.setHeader('Access-Control-Max-Age', '1728000')

      response.end()
      return
    }

    if (request.headers.origin) response.setHeader('Access-Control-Allow-Origin', request.headers.origin)
    if (u.pathname === '/') u.pathname = '/' + index

    if (u.pathname === '/favicon.ico') {
      response.statusCode = 404
      response.end()
      return
    }

    if (u.pathname === '/.json') {
      var json = toJSON()
      response.setHeader('Content-Type', 'application/json; charset=utf-8')
      response.setHeader('Content-Length', Buffer.byteLength(json))
      response.end(json)
      return
    }

    if (u.pathname === '/.m3u') {
      var playlist = toPlaylist()
      response.setHeader('Content-Type', 'application/x-mpegurl; charset=utf-8')
      response.setHeader('Content-Length', Buffer.byteLength(playlist))
      response.end(playlist)
      return
    }

    e.files.forEach(function (file, i) {
      if (u.pathname.slice(1) === file.name) u.pathname = '/' + i
    })

    var i = Number(u.pathname.slice(1))

    if (isNaN(i) || i >= e.files.length) {
      response.statusCode = 404
      response.end()
      return
    }

    var file = e.files[i]
    var range = request.headers.range
    range = range && rangeParser(file.length, range)[0]
    response.setHeader('Accept-Ranges', 'bytes')
    response.setHeader('Content-Type', getType(file.name))
    response.setHeader('transferMode.dlna.org', 'Streaming')
    response.setHeader('contentFeatures.dlna.org', 'DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=017000 00000000000000000000000000')
    if (!range) {
      response.setHeader('Content-Length', file.length)
      if (request.method === 'HEAD') return response.end()
      pump(file.createReadStream(), response)
      return
    }

    response.statusCode = 206
    response.setHeader('Content-Length', range.end - range.start + 1)
    response.setHeader('Content-Range', 'bytes ' + range.start + '-' + range.end + '/' + file.length)
    response.setHeader('transferMode.dlna.org', 'Streaming')
    response.setHeader('contentFeatures.dlna.org', 'DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=017000 00000000000000000000000000')
    if (request.method === 'HEAD') return response.end()
    pump(file.createReadStream(range), response)
  })

  server.on('connection', function (socket) {
    socket.setTimeout(36000000)
  })

  return server
}

module.exports = function (torrent, opts) {
  if (!opts) opts = {}

  // Parse blocklist
  if (opts.blocklist) opts.blocklist = parseBlocklist(opts.blocklist)

  var engine = torrentStream(torrent, xtend(opts, {port: opts.peerPort}))

  // Just want torrent-stream to list files.
  if (opts.list) return engine

  // Pause/Resume downloading as needed
  engine.on('uninterested', function () {
    engine.swarm.pause()
  })

//  engine.on('interested', function () {
//    engine.swarm.resume()
//  })

  engine.server = createServer(engine, opts)

  // Listen when torrent-stream is ready, by default a random port.
  engine.on('ready', function () {
    engine.server.listen(opts.port || 0, opts.hostname)
  })

  engine.listen()

  return engine
}
<|endoftext|>


<commit_before>'use strict'

module.exports = [
  {
    user: '@michal.brasna',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: '@jan.pavlovsky',
    services: ['peters', 'meat-market', 'globus', 'lokal-hamburk']
  },
  {
    user: '@ottokovarik',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: '@radim',
    services: ['tankovna', 'lokal-hamburk', 'u-zabranskych']
  },
  {
    user: '@tomas.pokorny',
    services: ['tankovna', 'lokal-hamburk']
  },
  {
    user: '@radek.carda',
    services: ['peters', 'globus', 'meat-market', 'lokal-hamburk']
  },
  {
    user: '@zdenek.cejka',
    services: ['peters', 'tankovna', 'u-sani', 'meat-market', 'globus']
  },
  {
    user: '@mafo',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: '@martin.kadlec',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: '@tomasbauer',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: '@snajby',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych']
  },
  {
    user: '@milan',
    services: ['peters', 'tankovna', 'u-sani', 'meat-market', 'lokal-hamburk', 'globus']
  },
  {
    user: '@vaclavhosticka',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych']
  },
  {
    user: '@ango',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-sani', 'u-tunelu']
  },
  {
    user: '@ondram',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-sani', 'u-tunelu']
  },
  {
    user: '@jenism',
    services: ['peters', 'meat-market', 'globus', 'lokal-hamburk']
  }
]
<commit_msg>notif pro @petrkrejcik<commit_after>'use strict'

module.exports = [
  {
    user: '@michal.brasna',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: '@jan.pavlovsky',
    services: ['peters', 'meat-market', 'globus', 'lokal-hamburk']
  },
  {
    user: '@ottokovarik',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: '@radim',
    services: ['tankovna', 'lokal-hamburk', 'u-zabranskych']
  },
  {
    user: '@tomas.pokorny',
    services: ['tankovna', 'lokal-hamburk']
  },
  {
    user: '@radek.carda',
    services: ['peters', 'globus', 'meat-market', 'lokal-hamburk']
  },
  {
    user: '@zdenek.cejka',
    services: ['peters', 'tankovna', 'u-sani', 'meat-market', 'globus']
  },
  {
    user: '@mafo',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: '@martin.kadlec',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: '@tomasbauer',
    services: ['tankovna', 'lokal-hamburk', 'globus']
  },
  {
    user: '@snajby',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych']
  },
  {
    user: '@milan',
    services: ['peters', 'tankovna', 'u-sani', 'meat-market', 'lokal-hamburk', 'globus']
  },
  {
    user: '@vaclavhosticka',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych']
  },
  {
    user: '@ango',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-sani', 'u-tunelu']
  },
  {
    user: '@ondram',
    services: ['peters', 'tankovna', 'meat-market', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-sani', 'u-tunelu']
  },
  {
    user: '@jenism',
    services: ['peters', 'meat-market', 'globus', 'lokal-hamburk']
  },
  {
    user: '@petrkrejcik',
    services: ['tankovna', 'lokal-hamburk', 'globus', 'u-zabranskych', 'u-tunelu']
  }
]
<|endoftext|>


<commit_before>(function ($, fluid) {

    fluid.defaults("gpii.uiOptions.enactors.magnifier", {
        gradeNames: ["fluid.viewComponent", "fluid.uiOptions.enactors", "autoInit"],
        preferenceMap: {
            "http://registry.gpii.org/common/magnification": {
                "model.value": "default"
            }
        },
        invokers: {
            set: {
                funcName: "gpii.uiOptions.enactors.magnifier.set",
                args: ["{arguments}.0", "{that}"]
            }
        },
        listeners: {
            onCreate: {
                listener: "{that}.set",
                args: "{that}.model.value"
            }
        }
    });

    gpii.uiOptions.enactors.magnifier.set = function (times, that) {
        //$(".flc-uiOptions-magnifier .flc-uiOptions-preview-per-setting-frame").contents().find("html").css("transform", "scale(" + times/100 + ")");
        that.container.css("transform", "scale(" + times/100 + ")");
        that.container.css("-webkit-transform", "scale(" + times/100 + ")");
    };

    gpii.uiOptions.enactors.magnifier.finalInit = function (that) {
        that.applier.modelChanged.addListener("value", function (newModel) {
            that.set(newModel.value);
        });
    };

})(jQuery, fluid);
<commit_msg>Setting magnification CSS transformation in a single call.<commit_after>(function ($, fluid) {

    fluid.defaults("gpii.uiOptions.enactors.magnifier", {
        gradeNames: ["fluid.viewComponent", "fluid.uiOptions.enactors", "autoInit"],
        preferenceMap: {
            "http://registry.gpii.org/common/magnification": {
                "model.value": "default"
            }
        },
        invokers: {
            set: {
                funcName: "gpii.uiOptions.enactors.magnifier.set",
                args: ["{arguments}.0", "{that}"]
            }
        },
        listeners: {
            onCreate: {
                listener: "{that}.set",
                args: "{that}.model.value"
            }
        }
    });

    gpii.uiOptions.enactors.magnifier.set = function (times, that) {
        that.container.css({"transform": "scale(" + times/100 + ")", "-webkit-transform": "scale(" + times/100 + ")"});
    };

    gpii.uiOptions.enactors.magnifier.finalInit = function (that) {
        that.applier.modelChanged.addListener("value", function (newModel) {
            that.set(newModel.value);
        });
    };

})(jQuery, fluid);
<|endoftext|>


<commit_before>var fs=require("fs");
var xml4kdb=require("ksana-indexer").xml4kdb;
var tokenize=require("ksana-analyzer").getAPI("simple1").tokenize;
var mkdirp=require("./mkdirp.js");
var filelist = fs.readFileSync("./jiangkangyur.lst","utf8").split(/\r?\n/);
var getMrkp = require("./getallmrkp.js");
//res.tags=[ [tags of seg 0 ], [tags of seg 1] ... ]
//res.texts [ {n:segid, t:"text"} , {n:segid, t:"text}, ]
//inject tags back to text

//tag [realpos, tagname, attribute, vpos==0 ]

var injectKetaka=function(start,end,text,mrkps) {
  var out=text;
  if(!mrkps)return out;
  console.log(mrkps);
  for(var i=0; i<mrkps.length; i++){//mrkps[chief,mrkpStart,mrkpLen,mrkpPb,mrkpText]
  	var mrkpStart = mrkps[i][1], mrkpLen = mrkps[i][2], mrkpText = mrkps[i][4];
  	//out = out.substr(0,mrkpStart-start)+"XXX"+mrkpText+'XXX'+out.substr(mrkpStart-start+mrkpLen);
    //if(mrkpText == " །") console.log(mrkpStart-start+2,mrkpStart-start+mrkpLen+2);
    //console.log(mrkpStart);
  	out = out.substr(0,mrkpStart-start+1)+mrkpText+out.substr(mrkpStart-start+mrkpLen+1);
  }
  //100      110     start and end
  //abcdefghijklmn   <-- text in XML

  // sort by s
  //s:105, l: 2, t="xyz"   //ketaka revision record
  //abcdexyzhi       <---output
  //out += text.substr(0,start);

	return out;
}

var injectTag=function(seg,tags,pageid,mrkps) {
	var text=seg.t;
	var out="", last=0,i=0, j=0;
	//tagoffset = tags[i][0]
	var mrkp = mrkps.filter(function(item){return item[0][3]===pageid})[0] ||[];
	//if(pageid == 4) console.log(mrkp);
	while (i<tags.length && tags[i][0]>=last) {

		var m = mrkp.filter(function(item){ return (last < item[1] && item[1] < tags[i][0]) });
		out+=injectKetaka(last, tags[i][0], text.substring(last,tags[i][0]), m);
		var tagname=tags[i][1];
		out+='<'+tagname;

		var attributes=tags[i][2];
		if (attributes) out+=" "+attributes; //has attribute
		out+='>';
		last=tags[i][0];

		i++;
	}
	m = mrkp.filter(function(item){ return last <= item[1] });
	out+=injectKetaka(last,text.length-1,text.substring(last),m);
	//console.log(out);
	return out;
}

var processFile = function(res,mrkps,vol,bampo) {
	var out=[];
	for(var i=0; i<res.tags.length; i++){
		var r=injectTag(res.texts[i],res.tags[i],i+1,mrkps);
		out.push(r);
	}
	var d = new Date();
	var date = d.toString().substr(4,11).replace(/ /g,"").toLowerCase();
	mkdirp.sync("../jiangkangyur_"+date+"/"+vol);
	fs.writeFileSync("../jiangkangyur_"+date+"/"+vol+"/"+bampo+".xml",out.join(""),"utf8");
	console.log("All files have been exported to xml, please see ../jiangkangyur_"+date+"/"+vol);
}

filelist.map(function(file){//file:../jiangkangyur/078/lj0302_001.xml
	var vol = file.match(/\/(\d+)\//)[1];
	var bampo = file.match(/lj\d+_\d+/)[0];
	var m=JSON.parse(fs.readFileSync("./"+vol+"/"+bampo.replace("lj","").replace("_","-")+".json","utf8"));
	var mrkps=getMrkp(m);
	//console.log(mrkps);
	var bampoText=fs.readFileSync(file,"utf8").replace(/\r?\n/g,"\n");//./lj0302_001.xml
	var res=xml4kdb.parseXML(bampoText,{segsep:"pb.id"});
	processFile(res,mrkps,vol,bampo);
});
// var r=injectTag(res.texts[2],res.tags[2],3);
// console.log(r);<commit_msg>solve the problem of trim (markups are trimmed, but tags are NOT trimmed)<commit_after>var fs=require("fs");
var xml4kdb=require("ksana-indexer").xml4kdb;
var tokenize=require("ksana-analyzer").getAPI("simple1").tokenize;
var mkdirp=require("./mkdirp.js");
var filelist = fs.readFileSync("./jiangkangyur.lst","utf8").split(/\r?\n/);
var getMrkp = require("./getallmrkp.js");
//res.tags=[ [tags of seg 0 ], [tags of seg 1] ... ]
//res.texts [ {n:segid, t:"text"} , {n:segid, t:"text}, ]
//inject tags back to text

//tag [realpos, tagname, attribute, vpos==0 ]
var trim=function(text) {
	var out=text;
	if(text[1] == " ") {
		out = text[0]+text.substr(2);
		//out = text.substr(2);
	}
	return out;
}

var beginWithSpace=function(text){
	if(text[1] == " ") return true;
	else return false;
}

var injectKetaka=function(start,end,text,mrkps) {
  var out=text;
  if(!mrkps)return out;
  for(var i=0; i<mrkps.length; i++){//mrkps[chief,mrkpStart,mrkpLen,mrkpPb,mrkpText]
  	var mrkpStart = mrkps[i][1], mrkpLen = mrkps[i][2], mrkpText = mrkps[i][4];
  	//console.log(mrkpStart,mrkpText);
  	//out = out.substr(0,mrkpStart-start)+"XXX"+mrkpText+'XXX'+out.substr(mrkpStart-start+mrkpLen);
    //if(mrkpText == " །") console.log(mrkpStart-start+2,mrkpStart-start+mrkpLen+2);
    //console.log(mrkpStart);
  	out = out.substr(0,mrkpStart-start+1)+mrkpText+out.substr(mrkpStart-start+mrkpLen+1);
  }
  //100      110     start and end
  //abcdefghijklmn   <-- text in XML

  // sort by s
  //s:105, l: 2, t="xyz"   //ketaka revision record
  //abcdexyzhi       <---output
  //out += text.substr(0,start);

	return out;
}

var injectTag=function(seg,tags,pageid,mrkps) {
	var text = seg.t;
	var bws = beginWithSpace(text);
	//var text=trim(seg.t);

	var out="", last=0,i=0, j=0;
	var mrkp = mrkps.filter(function(item){return item[0][3]===pageid})[0] ||[];
	if(bws) mrkp = mrkp.map(function(item){return [ item[0],item[1]+1,item[2],item[3],item[4] ]});
	if(pageid == 2 || pageid == 110){
		console.log(tags);
		console.log(mrkp);
	}
	while (i<tags.length && tags[i][0]>=last) {

		var m = mrkp.filter(function(item){ return (last <= item[1] && item[1] < tags[i][0]) });
		out+=injectKetaka(last, tags[i][0], text.substring(last,tags[i][0]), m);
		var tagname=tags[i][1];
		out+='<'+tagname;

		var attributes=tags[i][2];
		if (attributes) out+=" "+attributes; //has attribute
		out+='>';

		last=tags[i][0];
		i++;
	}
	m = mrkp.filter(function(item){ return last <= item[1] });
	out+=injectKetaka(last,text.length-1,text.substring(last),m);
	//console.log(out);
	return out;
}

var processFile = function(res,mrkps,vol,bampo) {
	var out=[];
	for(var i=0; i<res.tags.length; i++){
		var r=injectTag(res.texts[i],res.tags[i],i+1,mrkps);
		out.push(r);
	}
	var d = new Date();
	var date = d.toString().substr(4,11).replace(/ /g,"").toLowerCase();
	mkdirp.sync("../jiangkangyur_"+date+"/"+vol);
	fs.writeFileSync("../jiangkangyur_"+date+"/"+vol+"/"+bampo+".xml",out.join(""),"utf8");
	console.log("All files have been exported to xml, please see ../jiangkangyur_"+date+"/"+vol);
}

filelist.map(function(file){//file:../jiangkangyur/078/lj0302_001.xml
	var vol = file.match(/\/(\d+)\//)[1];
	var bampo = file.match(/lj\d+_\d+/)[0];
	var m=JSON.parse(fs.readFileSync("./"+vol+"/"+bampo.replace("lj","").replace("_","-")+".json","utf8"));
	var mrkps=getMrkp(m);
	//console.log(mrkps);
	var bampoText=fs.readFileSync(file,"utf8").replace(/\r?\n/g,"\n");//./lj0302_001.xml
	var res=xml4kdb.parseXML(bampoText,{segsep:"pb.id"});
	processFile(res,mrkps,vol,bampo);
});
// var r=injectTag(res.texts[2],res.tags[2],3);
// console.log(r);<|endoftext|>


<commit_before>var mysleep = require('sleep');
var chai = require('chai');
var parentDir = require('path');
var currentDir = parentDir.dirname(module.filename);
var Connection = require(parentDir.dirname(currentDir) + '/dist/api/connection').Connection
var StateType = require(parentDir.dirname(currentDir) + '/dist/api/api').StateType
var IRecipientInfo = require(parentDir.dirname(currentDir) + '/dist/api/api').IRecipientInfo
var path = parentDir.dirname(currentDir) + "/lib/libcxs.so";
var cxs = require('../dist/index.js')
var expect = chai.expect;
var assert = chai.assert;

const sleep = (time) => new Promise((res) => setTimeout(res, time))

const waitFor = async (predicate) => {
    if (!predicate()) {
        await sleep(1000)
        return waitFor(predicate)
    }
    return predicate()
}

// console.log(release(handle)) // tslint:disable-line
describe('A Connection object with ', function () {

    let connection;
    beforeEach(function() {
        const result = cxs.init_cxs('ENABLE_TEST_MODE')
        connection = new Connection(path)
    });

    //connection_create tests

    it('valid parameters in create should return success', function () {
        assert.equal(connection.create({
            id: "234",
            DIDself: "456",
            DIDremote: "0"}), 0)
    })

    it('null param in create should return success', function () {
        assert.equal(connection.create(null), 0)
    })

// connection_connect tests

    it(' a call to connect with connection already created should return success', function () {
        const waitForConnect = async (predicate) => {
            if (!predicate()) {
                await sleep(1000)
                return waitForConnect(predicate)
            }
            return predicate()
        }

        connection.create("connection_connect tests")

        var f = function(){
            console.log("****** inside waitforConnect ******")
            var state = connection.getState()
            console.log("****** state: " + state + " ******")
            return connection.connect({sms: true}) === 0
        }
        assert(waitForConnect(f))

        //assert.equal(connection.connect({sms: true}), 0)
    })

    it(' a call to create with no connection created should return unknown error', function () {
        assert.equal(connection.connect({sms: true}), 1003)
    })

// connection_get_data tests

    it('a call to get_data where connection exists should return back the connections data', function () {
        connection.create("dog, cat, man")
        var data = connection.getData()
        var jsonData = JSON.parse(data)
        assert.notEqual(data, null)
        assert.equal(jsonData.handle, connection.connectionHandle)
    })

    it('a call to get_data where connection doesnt exist should return a null value', function () {
        assert.equal(connection.getData(), null)
    })

    it('a call to get_data where connection was released should return a null value', function () {
        assert.equal(connection.create("connection_get_data tests"), 0)

        assert.equal(connection.connect({sms: true}), 0)
        assert.equal(connection.getState(),StateType.OfferSent)

        var data = connection.getData()
        assert.notEqual(data, null)
        assert.equal(connection.release(), 0)

        data = connection.getData()
        assert.equal(data, null)

    })
    it.only('a call to get_data where connection was released should return a null value', function () {
        /*
        var createConnection = function(){
            return new Promise((resolve,reject) =>{
                    resolve(connection.create("promise release"))
            });
        }

        var waitThreeSeconds= function(){
            return new Promise((resolve,reject) =>{
                mysleep.usleep(3000)
                resolve()
            });
        }

        var connectConnection = function() {
            return new Promise((resolve,reject) => {
                assert.equal(connection.connect({sms: true}),0)
                resolve()
            });
        }

        var connectGetState = function() {
            return new Promise((ressolve, reject) => {

                connection.getState()
                resolve()
            })
        }
        */
        // createConnection().then().then(connectConnection)
        const releaseTest = async () => {
            connection.create("promise release")
            console.log("###############################")
            // await sleep(4000)
            for (i = 1; i< 100000000; i++){

            }
            assert.equal(connection.connect({sms: true}),0)
            assert.equal(connection.getState(),StateType.OfferSent)

            var data = connection.getData()
            assert.notEqual(data, null)
            assert.equal(connection.release(), 0)

            data = connection.getData()
            assert.equal(data, null)
        }

        releaseTest()

        /*
        assert.equal(connection.create("promise release"), 0)

        assert.equal(connection.connect({sms: true}), 0)
        assert.equal(connection.getState(),StateType.OfferSent)

        var data = connection.getData()
        assert.notEqual(data, null)
        assert.equal(connection.release(), 0)

        data = connection.getData()
        assert.equal(data, null)
        */

    })

// connection_getState tests

    it('call to getState where connection exists should return success', function () {
        connection.create("connection_getState tests")
        mysleep.msleep(1000)
        connection.connect({sms: true})
        assert.equal(connection.getState(),StateType.OfferSent)

    })

    it('call to getState where no connection exists should have a state value of 0', function () {
        assert.equal(connection.getState(),StateType.None)

    })

    it('call to get_state where connection exists but not connected should have a state value of 1', function () {
        var connection = new Connection(path)

        connection.create("info2")
        mysleep.msleep(1000)
        assert.equal(connection.getState(), StateType.Initialized)
    })

// connection_release tests

    it('call to connection_release where connection exists should return success', function () {
        connection.create("connection_release tests")
        mysleep.msleep(1000)
        assert.equal(connection.connect({sms: true}), 0)
        assert.equal(connection.release(), 0)
        assert.equal(connection.connect({sms: true}), 1003)
        assert.equal(connection.getData(), null)
    })

    it('call to connection_release with no connection should return unknown error', function () {
        assert.equal(connection.release(), 1003)
    })

    it('connection and GC deletes object should return null whet get_data is called ', function () {
        const connection = new Connection(path)
        connection.create("msg")
        connection.connect({sms: true})
        const getData = connection.RUST_API.cxs_connection_get_data
        const handle = connection.connectionHandle
        assert.notEqual(connection.getData(handle), null)

        this.timeout(30000)
        delete connection
        global.gc()

        // this will timeout if condition is never met
        // get_data will return "" because the connection object was released
        return waitFor(() => !getData(handle))
    })

})
<commit_msg>Test pass with loop instead of sleep<commit_after>var mysleep = require('sleep');
var chai = require('chai');
var parentDir = require('path');
var currentDir = parentDir.dirname(module.filename);
var Connection = require(parentDir.dirname(currentDir) + '/dist/api/connection').Connection
var StateType = require(parentDir.dirname(currentDir) + '/dist/api/api').StateType
var IRecipientInfo = require(parentDir.dirname(currentDir) + '/dist/api/api').IRecipientInfo
var path = parentDir.dirname(currentDir) + "/lib/libcxs.so";
var cxs = require('../dist/index.js')
var expect = chai.expect;
var assert = chai.assert;

const sleep = (time) => new Promise((res) => setTimeout(res, time))

const waitFor = async (predicate) => {
    if (!predicate()) {
        await sleep(1000)
        return waitFor(predicate)
    }
    return predicate()
}

// console.log(release(handle)) // tslint:disable-line
describe('A Connection object with ', function () {

    let connection;
    beforeEach(function() {
        const result = cxs.init_cxs('ENABLE_TEST_MODE')
        connection = new Connection(path)
    });

    //connection_create tests

    it('valid parameters in create should return success', function () {
        assert.equal(connection.create({
            id: "234",
            DIDself: "456",
            DIDremote: "0"}), 0)
    })

    it('null param in create should return success', function () {
        assert.equal(connection.create(null), 0)
    })

// connection_connect tests

    it(' a call to connect with connection already created should return success', function () {
        const waitForConnect = async (predicate) => {
            if (!predicate()) {
                await sleep(1000)
                return waitForConnect(predicate)
            }
            return predicate()
        }

        connection.create("connection_connect tests")

        var f = function(){
            var state = connection.getState()
            return connection.connect({sms: true}) === 0
        }
        assert(waitForConnect(f))

    })

    it(' a call to create with no connection created should return unknown error', function () {
        assert.equal(connection.connect({sms: true}), 1003)
    })

// connection_get_data tests

    it('a call to get_data where connection exists should return back the connections data', function () {
        connection.create("dog, cat, man")
        var data = connection.getData()
        var jsonData = JSON.parse(data)
        assert.notEqual(data, null)
        assert.equal(jsonData.handle, connection.connectionHandle)
    })

    it('a call to get_data where connection doesnt exist should return a null value', function () {
        assert.equal(connection.getData(), null)
    })

    it('a call to get_data where connection was released should return a null value', function () {
        assert.equal(connection.create("connection_get_data tests"), 0)
        for (i = 1; i< 100000000; i++){
            // we need to wait
        }

        assert.equal(connection.connect({sms: true}), 0)
        assert.equal(connection.getState(),StateType.OfferSent)

        var data = connection.getData()
        assert.notEqual(data, null)
        assert.equal(connection.release(), 0)

        data = connection.getData()
        assert.equal(data, null)

    })

    // connection_getState tests

    it('call to getState where connection exists should return success', function () {
        connection.create("connection_getState tests")
        mysleep.msleep(1000)
        connection.connect({sms: true})
        assert.equal(connection.getState(),StateType.OfferSent)

    })

    it('call to getState where no connection exists should have a state value of 0', function () {
        assert.equal(connection.getState(),StateType.None)

    })

    it('call to get_state where connection exists but not connected should have a state value of 1', function () {
        var connection = new Connection(path)

        connection.create("info2")
        mysleep.msleep(1000)
        assert.equal(connection.getState(), StateType.Initialized)
    })

// connection_release tests

    it('call to connection_release where connection exists should return success', function () {
        connection.create("connection_release tests")
        mysleep.msleep(1000)
        assert.equal(connection.connect({sms: true}), 0)
        assert.equal(connection.release(), 0)
        assert.equal(connection.connect({sms: true}), 1003)
        assert.equal(connection.getData(), null)
    })

    it('call to connection_release with no connection should return unknown error', function () {
        assert.equal(connection.release(), 1003)
    })

    it('connection and GC deletes object should return null whet get_data is called ', function () {
        const connection = new Connection(path)
        connection.create("msg")
        connection.connect({sms: true})
        const getData = connection.RUST_API.cxs_connection_get_data
        const handle = connection.connectionHandle
        assert.notEqual(connection.getData(handle), null)

        this.timeout(30000)
        delete connection
        global.gc()

        // this will timeout if condition is never met
        // get_data will return "" because the connection object was released
        return waitFor(() => !getData(handle))
    })

})
<|endoftext|>


<commit_before>function Cube (element_id) {
	var DOM = {};
	DOM.cube = document.getElementById(element_id);
	DOM.side = {}
	DOM.value = {}
	DOM.score = document.getElementsByClassName('score');
	DOM.max = document.getElementsByClassName('max');
	this.DOM = DOM;

	var axis = ['z','-y','y','-z','-x','x'];
	var side = {};
	var coords = ['x','y','z'];

	var score = 0;
	var max_value = 0;

	function init () {
		coords = ['x','y','z'];
		score = 0;
		max_value = 0;

		DOM.cube.innerHTML = '

';
		DOM.cube.style.webkitTransform = new WebKitCSSMatrix();

		for (i in axis) DOM.side[axis[i]]=document.getElementById('side_'+axis[i]);
		for (i in axis) DOM.value[axis[i]]=document.getElementById('side_'+axis[i]).childNodes[0];
		for (i in axis) {side[axis[i]]=Math.round(Math.random()*2);}

		rotate3d(-1,-1,0,30); // initial rotation
		fill(); // initial filling
	};
	this.init = init;

	function fill () { // fill DOM.cube cube sides with appropriate values
		for (i in axis) {
			var element = DOM.side[axis[i]];
			var value = side[axis[i]];
			element.childNodes[0].innerHTML=value;
			var color = get_color(value);
			element.style.backgroundColor = 'rgba('+color.join(',')+',.5)';
		}
	}

	function animate_sides(reseted,increased) {
		DOM.value[reseted].style.fontSize='50%';
		DOM.value[increased].style.fontSize='150%';
		function return_state () {
			DOM.value[reseted].style.fontSize='100%'
			DOM.value[increased].style.fontSize='100%';
		}
		setTimeout(return_state,100);
		// DOM.value[reseted].style.fontSize='100%';
	}

	function make (direction) {
		var current_sides = {};
		current_sides.front = coords[2];
		current_sides.down = coords[1];
		current_sides.right = coords[0]
		current_sides.back = (current_sides.front.length==1)?'-'+current_sides.front:current_sides.front[1];
		current_sides.up = (current_sides.down.length==1)?'-'+current_sides.down:current_sides.down[1];
		current_sides.left = (current_sides.right.length==1)?'-'+current_sides.right:current_sides.right[1];
		// console.log(current_sides);
	    var front_value = side[current_sides.front];
	    // console.log(front_value)
	    var compare_value = side[current_sides[direction]];
	    // console.log(compare_value);

	   	if (front_value!=compare_value) {
	   		rotate(direction);
	   	} else {
	   		side[current_sides[direction]]++;
	   		score += side[current_sides[direction]];
	   		side[current_sides.front] = get_new_value();
	   		animate_sides(current_sides.front,current_sides[direction]);
	   		fill();
	   		for (i in DOM.score) {
	   			DOM.score[i].innerHTML = score;
	   		}
	   		// DOM.score.innerHTML = score;
	   		if (side[current_sides[direction]]>max_value) {
	   			max_value=side[current_sides[direction]];

		   		for (i in DOM.max) {
		   			DOM.max[i].innerHTML = max_value;
		   		}
	   			if (max_value==5) show_info({top:'CONGRATULATIONS!',header:side[current_sides[direction]],text:'If you get 10 - you will win'});
	   			if (max_value==10) show_info({top:'YOU WON!',header:side[current_sides[direction]],text:'So... can you get 15?'});
	   			if (max_value==15) show_info({top:'AMAZING!',header:side[current_sides[direction]],text:"I'll bet - you will do 20!"});
	   			if (max_value>=20) {
	   				var graz = ['CONGRATULATIONS!','UNBELIEVABLE!','What a wonder!','Is that real?'];
	   				graz = graz[Math.floor(Math.random()*graz.length)];

	   				show_info({top:graz,header:side[current_sides[direction]],text:'Try to get '+(side[current_sides[direction]]+1)});
	   			};

	   		}
	   		if (check_fail()) show_info({top:'So sorry ):',header:max_value,text:"... and "+score+" points - that's all what you've got.

tap or press space to restart",reset:true});
	   	};
	   	var prev_front = document.getElementsByClassName('front')[0];
	   	prev_front.className='side';
	   	DOM.side[coords[2]].className='side front';
	   	console.log(prev_front,DOM.side[coords[2]])
	};
	this.make = make;

	function get_new_value () {
		var values = unique([side['x'],side['-x'],side['y'],side['-y'],side['-z']]).sort();
		if (values[0]!=0) values.unshift(values[0]-1);
		var rand = 0;
        if (values.length==2) {
            rand = Math.round(Math.random());
        } else if (values.length>2) {
            rand = Math.round(Math.random()*9);
            rand = (rand < 4)?0:(rand < 9)?1:2;
        }

		return values[rand];
	}

	function check_fail () {
		var fail = false;
		if (   side['z']!=side['-y']
	        && side['z']!=side['-x']
	        && side['z']!=side['x']
	        && side['z']!=side['y']
	        && side['-z']!=side['-y']
	        && side['-z']!=side['-x']
	        && side['-z']!=side['x']
	        && side['-z']!=side['y']
	        && side['-y']!=side['-x']
	        && side['-y']!=side['x']
	        && side['y']!=side['-x']
	        && side['y']!=side['x']) fail = true;
		return fail;
	}

	function rotate (direction) {
		var t_angles = [0,0,0];
		// console.group(direction);
		switch (direction) {
	        case "up" : {
	            t_angles = convert_angles(1,0);
	        }; break;
	        case "down" : {
	            t_angles = convert_angles(-1,0);
	        }; break;
	        case "left" : {
	            t_angles = convert_angles(0,-1);
	        }; break;
	        case "right" : {
	            t_angles = convert_angles(0,1);
	        }; break;
	        default: throw new TypeError('direction must be "up", "down", "left" or "right", but not: "'+direction+'"');
	    };
		rotate3d(t_angles[0],t_angles[1],t_angles[2],90);
	}

	function convert_angles (x,y) {
		var new_angles = [0,0,0];

		// console.log(x,y);
		// 	console.log('coords before',coords);

			switch (coords[0]) {
				case "x" : new_angles[0]=x;break;
				case "-x" : new_angles[0]=-x;break;
				case "y" : new_angles[1]=x;break;
				case "-y" : new_angles[1]=-x;break;
				case "z" : new_angles[2]=x;break;
				case "-z" : new_angles[2]=-x;break;
			}
			switch (coords[1]) {
				case "x" : new_angles[0]=y;break;
				case "-x" : new_angles[0]=-y;break;
				case "y" : new_angles[1]=y;break;
				case "-y" : new_angles[1]=-y;break;
				case "z" : new_angles[2]=y;break;
				case "-z" : new_angles[2]=-y;break;
			}

			switch ([x,y].join(',')) {
				case "1,0": { //up
					var temp = coords[2];
					coords[2] = coords[1];
					coords[1] = (temp.length==1)?'-'+temp:temp[1];
				}; break;
				case "-1,0": { //down
					var temp = coords[1];
					coords[1] = coords[2];
					coords[2] = (temp.length==1)?'-'+temp:temp[1];
				}; break;
				case "0,1": { //right
					var temp = coords[0];
					coords[0] = coords[2];
					coords[2] = (temp.length==1)?'-'+temp:temp[1];
				}; break;
				case "0,-1": { //left
					var temp = coords[2];
					coords[2] = coords[0];
					coords[0] = (temp.length==1)?'-'+temp:temp[1];
				}; break;
			};

		// 	console.log('coords after',coords);
		// console.groupEnd();

		var tX = 0,tY=0,tZ=0;

		return new_angles;
	}

	function rotate3d(x,y,z,degree) {
		var matrix = new WebKitCSSMatrix(DOM.cube.style.webkitTransform);
		matrix = matrix.rotateAxisAngle(x,y,z,degree);
		DOM.cube.style.webkitTransform = matrix.toString();
	}

	init();

	return this;
}

var cube = new Cube('cube3d') // main cube object

function set_shortcut () {
	shortcut.add('up',function () {cube.make('up')});
	shortcut.add('down',function () {cube.make('down')});
	shortcut.add('left',function () {cube.make('left')});
	shortcut.add('Right',function () {cube.make('right')});

	$$('body').on('swipeUp',function () {cube.make('up')});
	$$('body').on('swipeDown',function () {cube.make('down')});
	$$('body').on('swipeLeft',function () {cube.make('left')});
	$$('body').on('swipeRight',function () {cube.make('right')});
}
set_shortcut();
function remove_shortcut () {
	shortcut.remove('up');
	shortcut.remove('down');
	shortcut.remove('left');
	shortcut.remove('Right');

	$$('body').off('swipeUp');
	$$('body').off('swipeDown');
	$$('body').off('swipeLeft');
	$$('body').off('swipeRight');
}

function get_color (value) {
	Math.seedrandom(value);
    var color = [(Math.round(Math.random()*150)+55),(Math.round(Math.random()*250)+5),(Math.round(Math.random()*250)+5)];
    Math.seedrandom();
    return color;
}

function unique(arr) {
  var obj = {};
  var result = [];

  nextInput:
  for(var i=0; i<arr.length; i++) {
    var str = arr[i];
    for(var j=0; j<result.length; j++) {
      if (result[j] == str) continue nextInput;
    }
    result.push(str);
  }

  return result;
}

function show_info (params) {
	var DOM_info = document.getElementById('info');
	var DOM_top = document.getElementById('info_top');
	var DOM_h1 = document.getElementById('info_h1');
	var DOM_p = document.getElementById('info_p');
	DOM_top.innerHTML = params.top;
	DOM_h1.innerHTML = params.header;
	DOM_p.innerHTML = params.text;
	DOM_info.style.backgroundColor = 'rgba('+get_color(params.header).join(',')+',.5)';
	DOM_info.style.display = 'block';

	setTimeout(function(){
		DOM_info.style.opacity = 1;
	},0);

		shortcut.add('space',function () {hide_info(params.reset)});
		$$('body').on('tap',function () {hide_info(params.reset)});

	remove_shortcut();
}
show_info({top:'',header:'hello'
		  ,text:'press ←,↑,→,↓
or
swipe ←,↑,→,↓.
Chosen side will increased, if it equal to front, cube will rotate otherwise.
 Press space or tap to close info.'});

function hide_info (reset) {
	var DOM_info = document.getElementById('info');
	DOM_info.style.backgroundColor = '';
	DOM_info.style.opacity = 0;
	setTimeout(function(){DOM_info.style.display = 'none';},0);
	shortcut.remove('space');
	$$('body').off('tap');
	set_shortcut();
	if (reset) cube.init();
}
<commit_msg>temporary disable webkitcssmatrix<commit_after>function Cube (element_id) {
	var DOM = {};
	DOM.cube = document.getElementById(element_id);
	DOM.side = {}
	DOM.value = {}
	DOM.score = document.getElementsByClassName('score');
	DOM.max = document.getElementsByClassName('max');
	this.DOM = DOM;

	var axis = ['z','-y','y','-z','-x','x'];
	var side = {};
	var coords = ['x','y','z'];

	var score = 0;
	var max_value = 0;

	function init () {
		coords = ['x','y','z'];
		score = 0;
		max_value = 0;

		DOM.cube.innerHTML = '

';
		// DOM.cube.style.webkitTransform = new WebKitCSSMatrix();

		for (i in axis) DOM.side[axis[i]]=document.getElementById('side_'+axis[i]);
		for (i in axis) DOM.value[axis[i]]=document.getElementById('side_'+axis[i]).childNodes[0];
		for (i in axis) {side[axis[i]]=Math.round(Math.random()*2);}

		rotate3d(-1,-1,0,30); // initial rotation
		fill(); // initial filling
	};
	this.init = init;

	function fill () { // fill DOM.cube cube sides with appropriate values
		for (i in axis) {
			var element = DOM.side[axis[i]];
			var value = side[axis[i]];
			element.childNodes[0].innerHTML=value;
			var color = get_color(value);
			element.style.backgroundColor = 'rgba('+color.join(',')+',.5)';
		}
	}

	function animate_sides(reseted,increased) {
		DOM.value[reseted].style.fontSize='50%';
		DOM.value[increased].style.fontSize='150%';
		function return_state () {
			DOM.value[reseted].style.fontSize='100%'
			DOM.value[increased].style.fontSize='100%';
		}
		setTimeout(return_state,100);
		// DOM.value[reseted].style.fontSize='100%';
	}

	function make (direction) {
		var current_sides = {};
		current_sides.front = coords[2];
		current_sides.down = coords[1];
		current_sides.right = coords[0]
		current_sides.back = (current_sides.front.length==1)?'-'+current_sides.front:current_sides.front[1];
		current_sides.up = (current_sides.down.length==1)?'-'+current_sides.down:current_sides.down[1];
		current_sides.left = (current_sides.right.length==1)?'-'+current_sides.right:current_sides.right[1];
		// console.log(current_sides);
	    var front_value = side[current_sides.front];
	    // console.log(front_value)
	    var compare_value = side[current_sides[direction]];
	    // console.log(compare_value);

	   	if (front_value!=compare_value) {
	   		rotate(direction);
	   	} else {
	   		side[current_sides[direction]]++;
	   		score += side[current_sides[direction]];
	   		side[current_sides.front] = get_new_value();
	   		animate_sides(current_sides.front,current_sides[direction]);
	   		fill();
	   		for (i in DOM.score) {
	   			DOM.score[i].innerHTML = score;
	   		}
	   		// DOM.score.innerHTML = score;
	   		if (side[current_sides[direction]]>max_value) {
	   			max_value=side[current_sides[direction]];

		   		for (i in DOM.max) {
		   			DOM.max[i].innerHTML = max_value;
		   		}
	   			if (max_value==5) show_info({top:'CONGRATULATIONS!',header:side[current_sides[direction]],text:'If you get 10 - you will win'});
	   			if (max_value==10) show_info({top:'YOU WON!',header:side[current_sides[direction]],text:'So... can you get 15?'});
	   			if (max_value==15) show_info({top:'AMAZING!',header:side[current_sides[direction]],text:"I'll bet - you will do 20!"});
	   			if (max_value>=20) {
	   				var graz = ['CONGRATULATIONS!','UNBELIEVABLE!','What a wonder!','Is that real?'];
	   				graz = graz[Math.floor(Math.random()*graz.length)];

	   				show_info({top:graz,header:side[current_sides[direction]],text:'Try to get '+(side[current_sides[direction]]+1)});
	   			};

	   		}
	   		if (check_fail()) show_info({top:'So sorry ):',header:max_value,text:"... and "+score+" points - that's all what you've got.

tap or press space to restart",reset:true});
	   	};
	   	var prev_front = document.getElementsByClassName('front')[0];
	   	prev_front.className='side';
	   	DOM.side[coords[2]].className='side front';
	   	console.log(prev_front,DOM.side[coords[2]])
	};
	this.make = make;

	function get_new_value () {
		var values = unique([side['x'],side['-x'],side['y'],side['-y'],side['-z']]).sort();
		if (values[0]!=0) values.unshift(values[0]-1);
		var rand = 0;
        if (values.length==2) {
            rand = Math.round(Math.random());
        } else if (values.length>2) {
            rand = Math.round(Math.random()*9);
            rand = (rand < 4)?0:(rand < 9)?1:2;
        }

		return values[rand];
	}

	function check_fail () {
		var fail = false;
		if (   side['z']!=side['-y']
	        && side['z']!=side['-x']
	        && side['z']!=side['x']
	        && side['z']!=side['y']
	        && side['-z']!=side['-y']
	        && side['-z']!=side['-x']
	        && side['-z']!=side['x']
	        && side['-z']!=side['y']
	        && side['-y']!=side['-x']
	        && side['-y']!=side['x']
	        && side['y']!=side['-x']
	        && side['y']!=side['x']) fail = true;
		return fail;
	}

	function rotate (direction) {
		var t_angles = [0,0,0];
		// console.group(direction);
		switch (direction) {
	        case "up" : {
	            t_angles = convert_angles(1,0);
	        }; break;
	        case "down" : {
	            t_angles = convert_angles(-1,0);
	        }; break;
	        case "left" : {
	            t_angles = convert_angles(0,-1);
	        }; break;
	        case "right" : {
	            t_angles = convert_angles(0,1);
	        }; break;
	        default: throw new TypeError('direction must be "up", "down", "left" or "right", but not: "'+direction+'"');
	    };
		rotate3d(t_angles[0],t_angles[1],t_angles[2],90);
	}

	function convert_angles (x,y) {
		var new_angles = [0,0,0];

		// console.log(x,y);
		// 	console.log('coords before',coords);

			switch (coords[0]) {
				case "x" : new_angles[0]=x;break;
				case "-x" : new_angles[0]=-x;break;
				case "y" : new_angles[1]=x;break;
				case "-y" : new_angles[1]=-x;break;
				case "z" : new_angles[2]=x;break;
				case "-z" : new_angles[2]=-x;break;
			}
			switch (coords[1]) {
				case "x" : new_angles[0]=y;break;
				case "-x" : new_angles[0]=-y;break;
				case "y" : new_angles[1]=y;break;
				case "-y" : new_angles[1]=-y;break;
				case "z" : new_angles[2]=y;break;
				case "-z" : new_angles[2]=-y;break;
			}

			switch ([x,y].join(',')) {
				case "1,0": { //up
					var temp = coords[2];
					coords[2] = coords[1];
					coords[1] = (temp.length==1)?'-'+temp:temp[1];
				}; break;
				case "-1,0": { //down
					var temp = coords[1];
					coords[1] = coords[2];
					coords[2] = (temp.length==1)?'-'+temp:temp[1];
				}; break;
				case "0,1": { //right
					var temp = coords[0];
					coords[0] = coords[2];
					coords[2] = (temp.length==1)?'-'+temp:temp[1];
				}; break;
				case "0,-1": { //left
					var temp = coords[2];
					coords[2] = coords[0];
					coords[0] = (temp.length==1)?'-'+temp:temp[1];
				}; break;
			};

		// 	console.log('coords after',coords);
		// console.groupEnd();

		var tX = 0,tY=0,tZ=0;

		return new_angles;
	}

	function rotate3d(x,y,z,degree) {
		// var matrix = new WebKitCSSMatrix(DOM.cube.style.webkitTransform);
		// matrix = matrix.rotateAxisAngle(x,y,z,degree);
		// DOM.cube.style.webkitTransform = matrix.toString();
	}

	init();

	return this;
}

var cube = new Cube('cube3d') // main cube object

function set_shortcut () {
	shortcut.add('up',function () {cube.make('up')});
	shortcut.add('down',function () {cube.make('down')});
	shortcut.add('left',function () {cube.make('left')});
	shortcut.add('Right',function () {cube.make('right')});

	$$('body').on('swipeUp',function () {cube.make('up')});
	$$('body').on('swipeDown',function () {cube.make('down')});
	$$('body').on('swipeLeft',function () {cube.make('left')});
	$$('body').on('swipeRight',function () {cube.make('right')});
}
set_shortcut();
function remove_shortcut () {
	shortcut.remove('up');
	shortcut.remove('down');
	shortcut.remove('left');
	shortcut.remove('Right');

	$$('body').off('swipeUp');
	$$('body').off('swipeDown');
	$$('body').off('swipeLeft');
	$$('body').off('swipeRight');
}

function get_color (value) {
	Math.seedrandom(value);
    var color = [(Math.round(Math.random()*150)+55),(Math.round(Math.random()*250)+5),(Math.round(Math.random()*250)+5)];
    Math.seedrandom();
    return color;
}

function unique(arr) {
  var obj = {};
  var result = [];

  nextInput:
  for(var i=0; i<arr.length; i++) {
    var str = arr[i];
    for(var j=0; j<result.length; j++) {
      if (result[j] == str) continue nextInput;
    }
    result.push(str);
  }

  return result;
}

function show_info (params) {
	var DOM_info = document.getElementById('info');
	var DOM_top = document.getElementById('info_top');
	var DOM_h1 = document.getElementById('info_h1');
	var DOM_p = document.getElementById('info_p');
	DOM_top.innerHTML = params.top;
	DOM_h1.innerHTML = params.header;
	DOM_p.innerHTML = params.text;
	DOM_info.style.backgroundColor = 'rgba('+get_color(params.header).join(',')+',.5)';
	DOM_info.style.display = 'block';

	setTimeout(function(){
		DOM_info.style.opacity = 1;
	},0);

		shortcut.add('space',function () {hide_info(params.reset)});
		$$('body').on('tap',function () {hide_info(params.reset)});

	remove_shortcut();
}
show_info({top:'',header:'hello'
		  ,text:'press ←,↑,→,↓
or
swipe ←,↑,→,↓.
Chosen side will increased, if it equal to front, cube will rotate otherwise.
 Press space or tap to close info.'});

function hide_info (reset) {
	var DOM_info = document.getElementById('info');
	DOM_info.style.backgroundColor = '';
	DOM_info.style.opacity = 0;
	setTimeout(function(){DOM_info.style.display = 'none';},0);
	shortcut.remove('space');
	$$('body').off('tap');
	set_shortcut();
	if (reset) cube.init();
}
<|endoftext|>


<commit_before>import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import Avatar from './avatar';
import AvatarOverlay from './avatar_overlay';
import RelativeTimestamp from './relative_timestamp';
import DisplayName from './display_name';
import MediaGallery from './media_gallery';
import VideoPlayer from './video_player';
import AttachmentList from './attachment_list';
import StatusContent from './status_content';
import StatusActionBar from './status_action_bar';
import { FormattedMessage } from 'react-intl';
import emojify from '../emoji';
import escapeTextContentForBrowser from 'escape-html';
import ImmutablePureComponent from 'react-immutable-pure-component';
import scheduleIdleTask from '../features/ui/util/schedule_idle_task';

class Status extends ImmutablePureComponent {

  static contextTypes = {
    router: PropTypes.object,
  };

  static propTypes = {
    status: ImmutablePropTypes.map,
    account: ImmutablePropTypes.map,
    wrapped: PropTypes.bool,
    onReply: PropTypes.func,
    onFavourite: PropTypes.func,
    onReblog: PropTypes.func,
    onDelete: PropTypes.func,
    onOpenMedia: PropTypes.func,
    onOpenVideo: PropTypes.func,
    onBlock: PropTypes.func,
    me: PropTypes.number,
    boostModal: PropTypes.bool,
    autoPlayGif: PropTypes.bool,
    muted: PropTypes.bool,
    intersectionObserverWrapper: PropTypes.object,
  };

  state = {
    isExpanded: false,
    isIntersecting: true, // assume intersecting until told otherwise
    isHidden: false, // set to true in requestIdleCallback to trigger un-render
  }

  // Avoid checking props that are functions (and whose equality will always
  // evaluate to false. See react-immutable-pure-component for usage.
  updateOnProps = [
    'status',
    'account',
    'wrapped',
    'me',
    'boostModal',
    'autoPlayGif',
    'muted',
  ]

  updateOnStates = ['isExpanded']

  shouldComponentUpdate (nextProps, nextState) {
    if (!nextState.isIntersecting && nextState.isHidden) {
      // It's only if we're not intersecting (i.e. offscreen) and isHidden is true
      // that either "isIntersecting" or "isHidden" matter, and then they're
      // the only things that matter.
      return this.state.isIntersecting || !this.state.isHidden;
    } else if (nextState.isIntersecting && !this.state.isIntersecting) {
      // If we're going from a non-intersecting state to an intersecting state,
      // (i.e. offscreen to onscreen), then we definitely need to re-render
      return true;
    }
    // Otherwise, diff based on "updateOnProps" and "updateOnStates"
    return super.shouldComponentUpdate(nextProps, nextState);
  }

  componentDidMount () {
    if (!this.props.intersectionObserverWrapper) {
      // TODO: enable IntersectionObserver optimization for notification statuses.
      // These are managed in notifications/index.js rather than status_list.js
      return;
    }
    this.props.intersectionObserverWrapper.observe(
      this.props.id,
      this.node,
      this.handleIntersection
    );
  }

  componentWillUnmount () {
    if (!this.props.intersectionObserverWrapper) {
      // TODO: enable IntersectionObserver optimization for notification statuses.
      // These are managed in notifications/index.js rather than status_list.js
      return;
    }

    this.props.intersectionObserverWrapper.unobserve(this.props.id, this.node);
  }

  handleIntersection = (entry) => {
    // Edge 15 doesn't support isIntersecting, but we can infer it
    // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12156111/
    // https://github.com/WICG/IntersectionObserver/issues/211
    const isIntersecting = (typeof entry.isIntersecting === 'boolean') ?
      entry.isIntersecting : entry.intersectionRect.height > 0;
    this.setState((prevState) => {
      if (prevState.isIntersecting && !isIntersecting) {
        scheduleIdleTask(this.hideIfNotIntersecting);
      }
      return {
        isIntersecting: isIntersecting,
        isHidden: false,
      };
    });
  }

  hideIfNotIntersecting = () => {
    // When the browser gets a chance, test if we're still not intersecting,
    // and if so, set our isHidden to true to trigger an unrender. The point of
    // this is to save DOM nodes and avoid using up too much memory.
    // See: https://github.com/tootsuite/mastodon/issues/2900
    this.setState((prevState) => ({ isHidden: !prevState.isIntersecting }));
  }

  saveHeight = () => {
    if (this.node && this.node.children.length !== 0) {
      this.height = this.node.clientHeight;
    }
  }

  handleRef = (node) => {
    this.node = node;
    this.saveHeight();
  }

  handleClick = () => {
    const { status } = this.props;
    this.context.router.push(`/statuses/${status.getIn(['reblog', 'id'], status.get('id'))}`);
  }

  handleAccountClick = (e) => {
    if (e.button === 0) {
      const id = Number(e.currentTarget.getAttribute('data-id'));
      e.preventDefault();
      this.context.router.push(`/accounts/${id}`);
    }
  }

  handleExpandedToggle = () => {
    this.setState({ isExpanded: !this.state.isExpanded });
  };

  render () {
    let media = null;
    let statusAvatar;
    const { status, account, ...other } = this.props;
    const { isExpanded, isIntersecting, isHidden } = this.state;

    if (status === null) {
      return null;
    }

    if (!isIntersecting && isHidden) {
      return (
        <div ref={this.handleRef} data-id={status.get('id')} style={{ height: `${this.height}px`, opacity: 0, overflow: 'hidden' }}>
          {status.getIn(['account', 'display_name']) || status.getIn(['account', 'username'])}
          {status.get('content')}

      );
    }

    if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') {
      let displayName = status.getIn(['account', 'display_name']);

      if (displayName.length === 0) {
        displayName = status.getIn(['account', 'username']);
      }

      const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) };

      return (

            <FormattedMessage id='status.reblogged_by' defaultMessage='{name} boosted' values={{ name:  }} />

          <Status {...other} wrapped status={status.get('reblog')} account={status.get('account')} />

      );
    }

    if (status.get('media_attachments').size > 0 && !this.props.muted) {
      if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) {

      } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
        media = <VideoPlayer media={status.getIn(['media_attachments', 0])} sensitive={status.get('sensitive')} onOpenVideo={this.props.onOpenVideo} />;
      } else {
        media = <MediaGallery media={status.get('media_attachments')} sensitive={status.get('sensitive')} height={110} onOpenMedia={this.props.onOpenMedia} autoPlayGif={this.props.autoPlayGif} />;
      }
    }

    if (account === undefined || account === null) {
      statusAvatar = <Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} />;
    }else{
      statusAvatar = <AvatarOverlay staticSrc={status.getIn(['account', 'avatar_static'])} overlaySrc={account.get('avatar_static')} />;
    }

    return (
      <div className={`status ${this.props.muted ? 'muted' : ''} status-${status.get('visibility')}`} data-id={status.get('id')} ref={this.handleRef}>

          <RelativeTimestamp timestamp={status.get('created_at')} />

              {statusAvatar}

            <DisplayName account={status.get('account')} />

        <StatusContent status={status} onClick={this.handleClick} expanded={isExpanded} onExpandedToggle={this.handleExpandedToggle} onHeightUpdate={this.saveHeight} />

        {media}

        <StatusActionBar {...this.props} />

    );
  }

}

export default Status;
<commit_msg>Don't attach IntersectionObserver for wrapped statuses (#3863)<commit_after>import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import Avatar from './avatar';
import AvatarOverlay from './avatar_overlay';
import RelativeTimestamp from './relative_timestamp';
import DisplayName from './display_name';
import MediaGallery from './media_gallery';
import VideoPlayer from './video_player';
import AttachmentList from './attachment_list';
import StatusContent from './status_content';
import StatusActionBar from './status_action_bar';
import { FormattedMessage } from 'react-intl';
import emojify from '../emoji';
import escapeTextContentForBrowser from 'escape-html';
import ImmutablePureComponent from 'react-immutable-pure-component';
import scheduleIdleTask from '../features/ui/util/schedule_idle_task';

class Status extends ImmutablePureComponent {

  static contextTypes = {
    router: PropTypes.object,
  };

  static propTypes = {
    status: ImmutablePropTypes.map,
    account: ImmutablePropTypes.map,
    wrapped: PropTypes.bool,
    onReply: PropTypes.func,
    onFavourite: PropTypes.func,
    onReblog: PropTypes.func,
    onDelete: PropTypes.func,
    onOpenMedia: PropTypes.func,
    onOpenVideo: PropTypes.func,
    onBlock: PropTypes.func,
    me: PropTypes.number,
    boostModal: PropTypes.bool,
    autoPlayGif: PropTypes.bool,
    muted: PropTypes.bool,
    intersectionObserverWrapper: PropTypes.object,
  };

  state = {
    isExpanded: false,
    isIntersecting: true, // assume intersecting until told otherwise
    isHidden: false, // set to true in requestIdleCallback to trigger un-render
  }

  // Avoid checking props that are functions (and whose equality will always
  // evaluate to false. See react-immutable-pure-component for usage.
  updateOnProps = [
    'status',
    'account',
    'wrapped',
    'me',
    'boostModal',
    'autoPlayGif',
    'muted',
  ]

  updateOnStates = ['isExpanded']

  shouldComponentUpdate (nextProps, nextState) {
    if (!nextState.isIntersecting && nextState.isHidden) {
      // It's only if we're not intersecting (i.e. offscreen) and isHidden is true
      // that either "isIntersecting" or "isHidden" matter, and then they're
      // the only things that matter.
      return this.state.isIntersecting || !this.state.isHidden;
    } else if (nextState.isIntersecting && !this.state.isIntersecting) {
      // If we're going from a non-intersecting state to an intersecting state,
      // (i.e. offscreen to onscreen), then we definitely need to re-render
      return true;
    }
    // Otherwise, diff based on "updateOnProps" and "updateOnStates"
    return super.shouldComponentUpdate(nextProps, nextState);
  }

  componentDidMount () {
    if (!this.props.intersectionObserverWrapper) {
      // TODO: enable IntersectionObserver optimization for notification statuses.
      // These are managed in notifications/index.js rather than status_list.js
      return;
    }
    this.props.intersectionObserverWrapper.observe(
      this.props.id,
      this.node,
      this.handleIntersection
    );
  }

  componentWillUnmount () {
    if (!this.props.intersectionObserverWrapper) {
      // TODO: enable IntersectionObserver optimization for notification statuses.
      // These are managed in notifications/index.js rather than status_list.js
      return;
    }

    this.props.intersectionObserverWrapper.unobserve(this.props.id, this.node);
  }

  handleIntersection = (entry) => {
    // Edge 15 doesn't support isIntersecting, but we can infer it
    // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12156111/
    // https://github.com/WICG/IntersectionObserver/issues/211
    const isIntersecting = (typeof entry.isIntersecting === 'boolean') ?
      entry.isIntersecting : entry.intersectionRect.height > 0;
    this.setState((prevState) => {
      if (prevState.isIntersecting && !isIntersecting) {
        scheduleIdleTask(this.hideIfNotIntersecting);
      }
      return {
        isIntersecting: isIntersecting,
        isHidden: false,
      };
    });
  }

  hideIfNotIntersecting = () => {
    // When the browser gets a chance, test if we're still not intersecting,
    // and if so, set our isHidden to true to trigger an unrender. The point of
    // this is to save DOM nodes and avoid using up too much memory.
    // See: https://github.com/tootsuite/mastodon/issues/2900
    this.setState((prevState) => ({ isHidden: !prevState.isIntersecting }));
  }

  saveHeight = () => {
    if (this.node && this.node.children.length !== 0) {
      this.height = this.node.clientHeight;
    }
  }

  handleRef = (node) => {
    this.node = node;
    this.saveHeight();
  }

  handleClick = () => {
    const { status } = this.props;
    this.context.router.push(`/statuses/${status.getIn(['reblog', 'id'], status.get('id'))}`);
  }

  handleAccountClick = (e) => {
    if (e.button === 0) {
      const id = Number(e.currentTarget.getAttribute('data-id'));
      e.preventDefault();
      this.context.router.push(`/accounts/${id}`);
    }
  }

  handleExpandedToggle = () => {
    this.setState({ isExpanded: !this.state.isExpanded });
  };

  render () {
    let media = null;
    let statusAvatar;

    // Exclude intersectionObserverWrapper from `other` variable
    // because intersection is managed in here.
    const { status, account, intersectionObserverWrapper, ...other } = this.props;
    const { isExpanded, isIntersecting, isHidden } = this.state;

    if (status === null) {
      return null;
    }

    if (!isIntersecting && isHidden) {
      return (
        <div ref={this.handleRef} data-id={status.get('id')} style={{ height: `${this.height}px`, opacity: 0, overflow: 'hidden' }}>
          {status.getIn(['account', 'display_name']) || status.getIn(['account', 'username'])}
          {status.get('content')}

      );
    }

    if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') {
      let displayName = status.getIn(['account', 'display_name']);

      if (displayName.length === 0) {
        displayName = status.getIn(['account', 'username']);
      }

      const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) };

      return (

            <FormattedMessage id='status.reblogged_by' defaultMessage='{name} boosted' values={{ name:  }} />

          <Status {...other} wrapped status={status.get('reblog')} account={status.get('account')} />

      );
    }

    if (status.get('media_attachments').size > 0 && !this.props.muted) {
      if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) {

      } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
        media = <VideoPlayer media={status.getIn(['media_attachments', 0])} sensitive={status.get('sensitive')} onOpenVideo={this.props.onOpenVideo} />;
      } else {
        media = <MediaGallery media={status.get('media_attachments')} sensitive={status.get('sensitive')} height={110} onOpenMedia={this.props.onOpenMedia} autoPlayGif={this.props.autoPlayGif} />;
      }
    }

    if (account === undefined || account === null) {
      statusAvatar = <Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} />;
    }else{
      statusAvatar = <AvatarOverlay staticSrc={status.getIn(['account', 'avatar_static'])} overlaySrc={account.get('avatar_static')} />;
    }

    return (
      <div className={`status ${this.props.muted ? 'muted' : ''} status-${status.get('visibility')}`} data-id={status.get('id')} ref={this.handleRef}>

          <RelativeTimestamp timestamp={status.get('created_at')} />

              {statusAvatar}

            <DisplayName account={status.get('account')} />

        <StatusContent status={status} onClick={this.handleClick} expanded={isExpanded} onExpandedToggle={this.handleExpandedToggle} onHeightUpdate={this.saveHeight} />

        {media}

        <StatusActionBar {...this.props} />

    );
  }

}

export default Status;
<|endoftext|>


<commit_before>//Dont change it
requirejs(['ext_editor_1', 'jquery_190', 'raphael_210', 'snap.svg_030'],
    function (ext, $, Raphael, Snap) {

        var cur_slide = {};

        ext.set_start_game(function (this_e) {
        });

        ext.set_process_in(function (this_e, data) {
            cur_slide = {};
            cur_slide["in"] = data[0];
            this_e.addAnimationSlide(cur_slide);
        });

        ext.set_process_out(function (this_e, data) {
            cur_slide["out"] = data[0];
        });

        ext.set_process_ext(function (this_e, data) {
            cur_slide.ext = data;
        });

        ext.set_process_err(function (this_e, data) {
            cur_slide['error'] = data[0];
            this_e.addAnimationSlide(cur_slide);
            cur_slide = {};
        });

        ext.set_animate_success_slide(function (this_e, options) {
            var $h = $(this_e.setHtmlSlide('

'));
            this_e.setAnimationHeight(115);
        });

        ext.set_animate_slide(function (this_e, data, options) {
            var $content = $(this_e.setHtmlSlide(ext.get_template('animation'))).find('.animation-content');
            if (!data) {
                console.log("data is undefined");
                return false;
            }

            //YOUR FUNCTION NAME
            var fname = 'checkio';

            var checkioInput = data.in;
            var checkioInputStr = fname + '(' + JSON.stringify(checkioInput) + ')';

            var failError = function (dError) {
                $content.find('.call').html(checkioInputStr);
                $content.find('.output').html(dError.replace(/\n/g, ","));

                $content.find('.output').addClass('error');
                $content.find('.call').addClass('error');
                $content.find('.answer').remove();
                $content.find('.explanation').remove();
                this_e.setAnimationHeight($content.height() + 60);
            };

            if (data.error) {
                failError(data.error);
                return false;
            }

            if (data.ext && data.ext.inspector_fail) {
                failError(data.ext.inspector_result_addon);
                return false;
            }

            $content.find('.call').html(checkioInputStr);
            $content.find('.output').html('Working...');

            if (data.ext) {
                var rightResult = data.ext["answer"];
                var userResult = data.out;
                var result = data.ext["result"];
                var result_addon = data.ext["result_addon"];

                //if you need additional info from tests (if exists)
                var explanation = data.ext["explanation"];
                $content.find('.output').html(' Your result: ' + JSON.stringify(userResult));
                if (!result) {
                    $content.find('.answer').html('Right result: ' + JSON.stringify(rightResult));
                    $content.find('.answer').addClass('error');
                    $content.find('.output').addClass('error');
                    $content.find('.call').addClass('error');
                }
                else {
                    $content.find('.answer').remove();
                }
            }
            else {
                $content.find('.answer').remove();
            }

            //Your code here about test explanation animation
            //$content.find(".explanation").html("Something text for example");
            //
            //
            //
            //
            //

            this_e.setAnimationHeight($content.height() + 60);

        });

        //This is for Tryit (but not necessary)
//        var $tryit;
//        ext.set_console_process_ret(function (this_e, ret) {
//            $tryit.find(".checkio-result").html("Result
" + ret);
//        });
//
//        ext.set_generate_animation_panel(function (this_e) {
//            $tryit = $(this_e.setHtmlTryIt(ext.get_template('tryit'))).find('.tryit-content');
//            $tryit.find('.bn-check').click(function (e) {
//                e.preventDefault();
//                this_e.sendToConsoleCheckiO("something");
//            });
//        });

        var colorOrange4 = "#F0801A";
        var colorOrange3 = "#FA8F00";
        var colorOrange2 = "#FAA600";
        var colorOrange1 = "#FABA00";

        var colorBlue4 = "#294270";
        var colorBlue3 = "#006CA9";
        var colorBlue2 = "#65A1CF";
        var colorBlue1 = "#8FC7ED";

        var colorGrey4 = "#737370";
        var colorGrey3 = "#9D9E9E";
        var colorGrey2 = "#C5C6C6";
        var colorGrey1 = "#EBEDED";

        var colorWhite = "#FFFFFF";
        //Your Additional functions or objects inside scope
        //
        //
        //

    }
);
<commit_msg>draft graphic<commit_after>//Dont change it
requirejs(['ext_editor_1', 'jquery_190', 'raphael_210', 'snap.svg_030'],
    function (ext, $, Raphael, Snap) {

        var cur_slide = {};

        ext.set_start_game(function (this_e) {
        });

        ext.set_process_in(function (this_e, data) {
            cur_slide = {};
            cur_slide["in"] = data[0];
            this_e.addAnimationSlide(cur_slide);
        });

        ext.set_process_out(function (this_e, data) {
            cur_slide["out"] = data[0];
        });

        ext.set_process_ext(function (this_e, data) {
            cur_slide.ext = data;
        });

        ext.set_process_err(function (this_e, data) {
            cur_slide['error'] = data[0];
            this_e.addAnimationSlide(cur_slide);
            cur_slide = {};
        });

        ext.set_animate_success_slide(function (this_e, options) {
            var $h = $(this_e.setHtmlSlide('

'));
            this_e.setAnimationHeight(115);
        });

        ext.set_animate_slide(function (this_e, data, options) {
            var $content = $(this_e.setHtmlSlide(ext.get_template('animation'))).find('.animation-content');
            if (!data) {
                console.log("data is undefined");
                return false;
            }

            //YOUR FUNCTION NAME
            var fname = 'clock_angle';

            var checkioInput = data.in || "14:30";
            var checkioInputStr = fname + '(' + JSON.stringify(checkioInput) + ')';

            var failError = function (dError) {
                $content.find('.call').html(checkioInputStr);
                $content.find('.output').html(dError.replace(/\n/g, ","));

                $content.find('.output').addClass('error');
                $content.find('.call').addClass('error');
                $content.find('.answer').remove();
                $content.find('.explanation').remove();
                this_e.setAnimationHeight($content.height() + 60);
            };

            if (data.error) {
                failError(data.error);
                return false;
            }

            if (data.ext && data.ext.inspector_fail) {
                failError(data.ext.inspector_result_addon);
                return false;
            }

            $content.find('.call').html(checkioInputStr);
            $content.find('.output').html('Working...');

            var svg = new SVG($content.find(".explanation")[0]);
            svg.draw(checkioInput);

            if (data.ext) {
                var rightResult = data.ext["answer"];
                var userResult = data.out;
                var result = data.ext["result"];
                var result_addon = data.ext["result_addon"];

                //if you need additional info from tests (if exists)
                var explanation = data.ext["explanation"];
                $content.find('.output').html(' Your result: ' + JSON.stringify(userResult));
                if (!result) {
                    $content.find('.answer').html('Right result: ' + JSON.stringify(rightResult));
                    $content.find('.answer').addClass('error');
                    $content.find('.output').addClass('error');
                    $content.find('.call').addClass('error');
                }
                else {
                    $content.find('.answer').remove();
                }
            }
            else {
                $content.find('.answer').remove();
            }

            //Your code here about test explanation animation
            //$content.find(".explanation").html("Something text for example");
            //
            //
            //
            //
            //

            this_e.setAnimationHeight($content.height() + 60);

        });

        //This is for Tryit (but not necessary)
//        var $tryit;
//        ext.set_console_process_ret(function (this_e, ret) {
//            $tryit.find(".checkio-result").html("Result
" + ret);
//        });
//
//        ext.set_generate_animation_panel(function (this_e) {
//            $tryit = $(this_e.setHtmlTryIt(ext.get_template('tryit'))).find('.tryit-content');
//            $tryit.find('.bn-check').click(function (e) {
//                e.preventDefault();
//                this_e.sendToConsoleCheckiO("something");
//            });
//        });

        function SVG(dom) {

            var colorOrange4 = "#F0801A";
            var colorOrange3 = "#FA8F00";
            var colorOrange2 = "#FAA600";
            var colorOrange1 = "#FABA00";

            var colorBlue4 = "#294270";
            var colorBlue3 = "#006CA9";
            var colorBlue2 = "#65A1CF";
            var colorBlue1 = "#8FC7ED";

            var colorGrey4 = "#737370";
            var colorGrey3 = "#9D9E9E";
            var colorGrey2 = "#C5C6C6";
            var colorGrey1 = "#EBEDED";

            var colorWhite = "#FFFFFF";

            var pad = 10;
            var paper;

            var R = 150;
            var inR = 135;

            var aText = {"font-family": "Roboto, Arial, sans", "stroke": colorBlue4, "font-size": 30};
            var aHour = {"stroke": colorBlue3, "stroke-width": 6};
            var aMinute = {"stroke": colorBlue3, "stroke-width": 4};
            var aClock = {"stroke": colorBlue4, "fill": colorBlue1, "stroke-width": 3};

            this.draw = function(data) {
                paper = Raphael(dom, (R + pad) * 2, (R + pad) * 2);
                paper.circle(R +pad,  R + pad, R).attr(aClock);
                paper.circle(R +pad,  R + pad, 1).attr(aClock);

                for (var i = 1; i <= 12; i++) {
                    var angle = (90 - 30 * i) / (Math.PI * 2);
                    var x = Math.cos(angle) * inR + R + pad;
                    var y = -1 * Math.sin(angle) * inR + R + pad;
                    paper.text(x, y, i).attr(aText);
                }
            }

        }

        //Your Additional functions or objects inside scope
        //
        //
        //

    }
);
<|endoftext|>


<commit_before>/**
 * Dashboard PageSpeed Widget component.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * WordPress dependencies
 */
import { useCallback, useEffect } from '@wordpress/element';
import { __, _x, sprintf } from '@wordpress/i18n';
import { addQueryArgs } from '@wordpress/url';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import ProgressBar from '../../../components/progress-bar';
import Link from '../../../components/link';
import LabReportMetrics from './LabReportMetrics';
import FieldReportMetrics from './FieldReportMetrics';
import { STORE_NAME as CORE_FORMS } from '../../../googlesitekit/datastore/forms/constants';
import { STORE_NAME as CORE_SITE } from '../../../googlesitekit/datastore/site/constants';
import {
	STORE_NAME,
	STRATEGY_MOBILE,
	STRATEGY_DESKTOP,
	DATA_SRC_FIELD,
	DATA_SRC_LAB,
	FORM_DASH_WIDGET,
} from '../datastore/constants';
import { sanitizeHTML } from '../../../util';
const { useSelect, useDispatch } = Data;

export default function DashboardPageSpeed() {
	// TODO: replace global with selector.
	const permalink = global._googlesitekitLegacyData.permaLink;
	const referenceURL = useSelect( ( select ) => select( CORE_SITE ).getReferenceSiteURL() );
	const url = permalink || referenceURL;
	const reportMobile = useSelect( ( select ) => select( STORE_NAME ).getReport( url, STRATEGY_MOBILE ) );
	const reportDesktop = useSelect( ( select ) => select( STORE_NAME ).getReport( url, STRATEGY_DESKTOP ) );
	const strategy = useSelect( ( select ) => select( CORE_FORMS ).getValue( FORM_DASH_WIDGET, 'strategy' ) ) || STRATEGY_MOBILE;
	const dataSrc = useSelect( ( select ) => select( CORE_FORMS ).getValue( FORM_DASH_WIDGET, 'dataSrc' ) );

	const { setValues } = useDispatch( CORE_FORMS );
	const setStrategyMobile = useCallback( () => setValues( FORM_DASH_WIDGET, { strategy: STRATEGY_MOBILE } ), [] );
	const setStrategyDesktop = useCallback( () => setValues( FORM_DASH_WIDGET, { strategy: STRATEGY_DESKTOP } ), [] );
	const setDataSrcField = useCallback( () => setValues( FORM_DASH_WIDGET, { dataSrc: DATA_SRC_FIELD } ), [] );
	const setDataSrcLab = useCallback( () => setValues( FORM_DASH_WIDGET, { dataSrc: DATA_SRC_LAB } ), [] );

	// Set the default data source based on report data.
	useEffect( () => {
		if ( ! reportMobile || ! reportDesktop ) {
			return;
		}
		if ( reportMobile?.loadingExperience?.metrics && reportDesktop?.loadingExperience?.metrics ) {
			setDataSrcField();
		} else {
			setDataSrcLab();
		}
	}, [ reportMobile, reportDesktop ] );

	if ( ! reportMobile || ! reportDesktop || ! dataSrc ) {
		return <ProgressBar />;
	}

	const reportData = strategy === STRATEGY_MOBILE ? reportMobile : reportDesktop;
	const footerLinkHTML = sprintf(
		/* translators: 1: link attributes, 2: translated service name */
		__( 'View details at %2$s', 'google-site-kit' ),
		`href="${ addQueryArgs( 'https://developers.google.com/speed/pagespeed/insights/', { url } ) }" class="googlesitekit-cta-link googlesitekit-cta-link--external" target="_blank"`,
		_x( 'PageSpeed Insights', 'Service name', 'google-site-kit' )
	);

	return (

					{ /* Temporarily use danger as an "active" state */ }
					<Link
						danger={ dataSrc === DATA_SRC_FIELD }
						onClick={ setDataSrcField }
					>
						{ __( 'In the Field', 'google-site-kit' ) }
					</Link>
					<Link
						danger={ dataSrc === DATA_SRC_LAB }
						onClick={ setDataSrcLab }
					>
						{ __( 'In the Lab', 'google-site-kit' ) }
					</Link>

					<Link
						danger={ strategy === STRATEGY_MOBILE }
						onClick={ setStrategyMobile }
					>
						mobile
					</Link>
					<Link
						danger={ strategy === STRATEGY_DESKTOP }
						onClick={ setStrategyDesktop }
					>
						desktop
					</Link>

				{ dataSrc === DATA_SRC_LAB && <LabReportMetrics data={ reportData } /> }
				{ dataSrc === DATA_SRC_FIELD && <FieldReportMetrics data={ reportData } /> }

	);
}
<commit_msg>Use getCurrentEntityURL in PageSpeed Insights widget.<commit_after>/**
 * Dashboard PageSpeed Widget component.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * WordPress dependencies
 */
import { useCallback, useEffect } from '@wordpress/element';
import { __, _x, sprintf } from '@wordpress/i18n';
import { addQueryArgs } from '@wordpress/url';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import ProgressBar from '../../../components/progress-bar';
import Link from '../../../components/link';
import LabReportMetrics from './LabReportMetrics';
import FieldReportMetrics from './FieldReportMetrics';
import { STORE_NAME as CORE_FORMS } from '../../../googlesitekit/datastore/forms/constants';
import { STORE_NAME as CORE_SITE } from '../../../googlesitekit/datastore/site/constants';
import {
	STORE_NAME,
	STRATEGY_MOBILE,
	STRATEGY_DESKTOP,
	DATA_SRC_FIELD,
	DATA_SRC_LAB,
	FORM_DASH_WIDGET,
} from '../datastore/constants';
import { sanitizeHTML } from '../../../util';
const { useSelect, useDispatch } = Data;

export default function DashboardPageSpeed() {
	const entityURL = useSelect( ( select ) => select( CORE_SITE ).getCurrentEntityURL() );
	const referenceURL = useSelect( ( select ) => select( CORE_SITE ).getReferenceSiteURL() );
	const url = entityURL !== null ? entityURL : referenceURL;

	const reportMobile = useSelect( ( select ) => select( STORE_NAME ).getReport( url, STRATEGY_MOBILE ) );
	const reportDesktop = useSelect( ( select ) => select( STORE_NAME ).getReport( url, STRATEGY_DESKTOP ) );
	const strategy = useSelect( ( select ) => select( CORE_FORMS ).getValue( FORM_DASH_WIDGET, 'strategy' ) ) || STRATEGY_MOBILE;
	const dataSrc = useSelect( ( select ) => select( CORE_FORMS ).getValue( FORM_DASH_WIDGET, 'dataSrc' ) );

	const { setValues } = useDispatch( CORE_FORMS );
	const setStrategyMobile = useCallback( () => setValues( FORM_DASH_WIDGET, { strategy: STRATEGY_MOBILE } ), [] );
	const setStrategyDesktop = useCallback( () => setValues( FORM_DASH_WIDGET, { strategy: STRATEGY_DESKTOP } ), [] );
	const setDataSrcField = useCallback( () => setValues( FORM_DASH_WIDGET, { dataSrc: DATA_SRC_FIELD } ), [] );
	const setDataSrcLab = useCallback( () => setValues( FORM_DASH_WIDGET, { dataSrc: DATA_SRC_LAB } ), [] );

	// Set the default data source based on report data.
	useEffect( () => {
		if ( ! reportMobile || ! reportDesktop ) {
			return;
		}
		if ( reportMobile?.loadingExperience?.metrics && reportDesktop?.loadingExperience?.metrics ) {
			setDataSrcField();
		} else {
			setDataSrcLab();
		}
	}, [ reportMobile, reportDesktop ] );

	if ( ! url || ! reportMobile || ! reportDesktop || ! dataSrc ) {
		return <ProgressBar />;
	}

	const reportData = strategy === STRATEGY_MOBILE ? reportMobile : reportDesktop;
	const footerLinkHTML = sprintf(
		/* translators: 1: link attributes, 2: translated service name */
		__( 'View details at %2$s', 'google-site-kit' ),
		`href="${ addQueryArgs( 'https://developers.google.com/speed/pagespeed/insights/', { url } ) }" class="googlesitekit-cta-link googlesitekit-cta-link--external" target="_blank"`,
		_x( 'PageSpeed Insights', 'Service name', 'google-site-kit' )
	);

	return (

					{ /* Temporarily use danger as an "active" state */ }
					<Link
						danger={ dataSrc === DATA_SRC_FIELD }
						onClick={ setDataSrcField }
					>
						{ __( 'In the Field', 'google-site-kit' ) }
					</Link>
					<Link
						danger={ dataSrc === DATA_SRC_LAB }
						onClick={ setDataSrcLab }
					>
						{ __( 'In the Lab', 'google-site-kit' ) }
					</Link>

					<Link
						danger={ strategy === STRATEGY_MOBILE }
						onClick={ setStrategyMobile }
					>
						mobile
					</Link>
					<Link
						danger={ strategy === STRATEGY_DESKTOP }
						onClick={ setStrategyDesktop }
					>
						desktop
					</Link>

				{ dataSrc === DATA_SRC_LAB && <LabReportMetrics data={ reportData } /> }
				{ dataSrc === DATA_SRC_FIELD && <FieldReportMetrics data={ reportData } /> }

	);
}
<|endoftext|>


<commit_before>function performSearch(input)
{
	var dataSet = document.getElementById(input.getAttribute("data-set"));
	for (i = 0; i < dataSet.childElementCount; ++i)
	{
		var child = dataSet.children[i];
		var name = child.getAttribute("data-" + input.getAttribute("data-key"));
		if (name.toLowerCase().indexOf(input.value.toLowerCase()) != -1)
			child.className = "";
		else
			child.className = "hidden";
	}
}
<commit_msg>js: use classList API<commit_after>function performSearch(input)
{
	var dataSet = document.getElementById(input.getAttribute("data-set"));
	for (i = 0; i < dataSet.childElementCount; ++i)
	{
		var child = dataSet.children[i];
		var name = child.getAttribute("data-" + input.getAttribute("data-key"));
		if (name.toLowerCase().indexOf(input.value.toLowerCase()) != -1)
			child.classList.remove("hidden");
		else
			child.classList.add("hidden");
	}
}
<|endoftext|>


<commit_before>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const http = require("http");

/** @typedef {import("../Compiler")} Compiler */

/**
 * @param {Compiler} compiler compiler
 * @param {string} client client reference
 * @param {function(Error?, any?): void} callback callback
 * @returns {void}
 */
module.exports = (compiler, client, callback) => {
	const logger = compiler.getInfrastructureLogger("LazyCompilationBackend");
	const activeModules = new Map();
	const prefix = "/lazy-compilation-using-";

	const server = http.createServer((req, res) => {
		const keys = req.url.slice(prefix.length).split("@");
		req.socket.on("close", () => {
			setTimeout(() => {
				for (const key of keys) {
					const oldValue = activeModules.get(key) || 0;
					activeModules.set(key, oldValue - 1);
					if (oldValue === 1) {
						logger.log(
							`${key} is no longer in use. Next compilation will skip this module.`
						);
					}
				}
			}, 120000);
		});
		req.socket.setNoDelay(true);
		res.writeHead(200, {
			"content-type": "text/event-stream",
			"Access-Control-Allow-Origin": "*"
		});
		res.write("\n");
		let moduleActivated = false;
		for (const key of keys) {
			const oldValue = activeModules.get(key) || 0;
			activeModules.set(key, oldValue + 1);
			if (oldValue === 0) {
				logger.log(`${key} is now in use and will be compiled.`);
				moduleActivated = true;
			}
		}
		if (moduleActivated && compiler.watching) compiler.watching.invalidate();
	});
	server.listen(err => {
		if (err) return callback(err);
		const addr = server.address();
		if (typeof addr === "string") throw new Error("addr must not be a string");
		const urlBase =
			addr.address === "::" || addr.address === "0.0.0.0"
				? `http://localhost:${addr.port}`
				: addr.family === "IPv6"
				? `http://[${addr.address}]:${addr.port}`
				: `http://${addr.address}:${addr.port}`;
		logger.log(
			`Server-Sent-Events server for lazy compilation open at ${urlBase}.`
		);
		callback(null, {
			dispose(callback) {
				server.close(callback);
			},
			module(originalModule) {
				const key = `${encodeURIComponent(
					originalModule.identifier().replace(/\\/g, "/").replace(/@/g, "_")
				).replace(/%(2F|3A|24|26|2B|2C|3B|3D|3A)/g, decodeURIComponent)}`;
				const active = activeModules.get(key) > 0;
				return {
					client: `${client}?${encodeURIComponent(urlBase + prefix)}`,
					data: key,
					active
				};
			}
		});
	});
};
<commit_msg>improve disposing of lazy compilation backend server<commit_after>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const http = require("http");

/** @typedef {import("../Compiler")} Compiler */

/**
 * @param {Compiler} compiler compiler
 * @param {string} client client reference
 * @param {function(Error?, any?): void} callback callback
 * @returns {void}
 */
module.exports = (compiler, client, callback) => {
	const logger = compiler.getInfrastructureLogger("LazyCompilationBackend");
	const activeModules = new Map();
	const prefix = "/lazy-compilation-using-";

	const server = http.createServer((req, res) => {
		const keys = req.url.slice(prefix.length).split("@");
		req.socket.on("close", () => {
			setTimeout(() => {
				for (const key of keys) {
					const oldValue = activeModules.get(key) || 0;
					activeModules.set(key, oldValue - 1);
					if (oldValue === 1) {
						logger.log(
							`${key} is no longer in use. Next compilation will skip this module.`
						);
					}
				}
			}, 120000);
		});
		req.socket.setNoDelay(true);
		res.writeHead(200, {
			"content-type": "text/event-stream",
			"Access-Control-Allow-Origin": "*"
		});
		res.write("\n");
		let moduleActivated = false;
		for (const key of keys) {
			const oldValue = activeModules.get(key) || 0;
			activeModules.set(key, oldValue + 1);
			if (oldValue === 0) {
				logger.log(`${key} is now in use and will be compiled.`);
				moduleActivated = true;
			}
		}
		if (moduleActivated && compiler.watching) compiler.watching.invalidate();
	});
	let isClosing = false;
	/** @type {Set<import("net").Socket>} */
	const sockets = new Set();
	server.on("connection", socket => {
		sockets.add(socket);
		socket.on("close", () => {
			sockets.delete(socket);
		});
		if (isClosing) socket.destroy();
	});
	server.listen(err => {
		if (err) return callback(err);
		const addr = server.address();
		if (typeof addr === "string") throw new Error("addr must not be a string");
		const urlBase =
			addr.address === "::" || addr.address === "0.0.0.0"
				? `http://localhost:${addr.port}`
				: addr.family === "IPv6"
				? `http://[${addr.address}]:${addr.port}`
				: `http://${addr.address}:${addr.port}`;
		logger.log(
			`Server-Sent-Events server for lazy compilation open at ${urlBase}.`
		);
		callback(null, {
			dispose(callback) {
				isClosing = true;
				server.close(err => {
					callback(err);
				});
				for (const socket of sockets) {
					socket.destroy(new Error("Server is disposing"));
				}
			},
			module(originalModule) {
				const key = `${encodeURIComponent(
					originalModule.identifier().replace(/\\/g, "/").replace(/@/g, "_")
				).replace(/%(2F|3A|24|26|2B|2C|3B|3D|3A)/g, decodeURIComponent)}`;
				const active = activeModules.get(key) > 0;
				return {
					client: `${client}?${encodeURIComponent(urlBase + prefix)}`,
					data: key,
					active
				};
			}
		});
	});
};
<|endoftext|>