text:
"""
Generates increasingly bigger/more Service Chain requirements for a
network topology, reports how well the algorithm performed.
"""

import getopt
import logging
import math
import random
import sys
import traceback

import CarrierTopoBuilder
import MappingAlgorithms
import UnifyExceptionTypes as uet

from collections import OrderedDict

from nffg_lib.nffg import NFFG, NFFGToolBox

def gen_seq():
  while True:
    yield int(math.floor(random.random() * 999999999))

log = logging.getLogger("StressTest")
log.setLevel(logging.INFO)
logging.basicConfig(format='%(levelname)s:%(name)s:%(message)s')
# dictionary of newly added VNF-s keyed by the number of 'test_lvl' when it
# was added.

helpmsg = """StressTest.py options are:
   -h                Print this message help message.
   -o                The output file where the result shall be printed.
   --loops           All Service Chains will be loops.
   --fullremap       Ignores all VNF mappings in the substrate network.
   --vnf_sharing=p   Sets the ratio of shared and not shared VNF-s.
   --request_seed=i  Provides seed for the random generator.

   --bw_factor=f     Controls the importance between bandwidth, infra resources
   --res_factor=f    and distance in latency during the mapping process. The
   --lat_factor=f    factors are advised to be summed to 3, if any is given the
                     others shall be given too!
   --bt_limit=i      Backtracking depth limit of the mapping algorithm (def.: 6).
   --bt_br_factor=i  Branching factor of the backtracking procedure of the
                     mapping algorithm (default is 3).

   --multiple_scs           One request will contain at least 2 chains with vnf sharing
                            probability defined by "--vnf_sharing_same_sg" option.
   --vnf_sharing_same_sg=p  The conditional probablilty of sharing a VNF with the
                            current Service Graph, if we need to share a VNF
                            determined by "--vnf_sharing"
   --max_sc_count=i         Determines how many chains should one request contain
                            at most.

   --batch_length=i  The number of Service Graphs, that should be batched and
                     mapped together by the algorithm.
   --shareable_sg_count=i   The number of last 'i' Service Graphs which could
                            be used for sharing VNFs. Default value is unlimited.
   --sliding_share   If not set, the set of shareable SG-s is emptied after
                     successfull batched mapping.
   --use_saps_once   If set, all SAPs can only be used once as SC origin and
                     once as SC destination.
"""

def _shareVNFFromEarlierSG(nffg, running_nfs, nfs_this_sc, p):
  sumlen = sum([l*i for l,i in zip([len(running_nfs[n]) for n in running_nfs],
                                   xrange(1,len(running_nfs)+1))])
  i = 0
  ratio = float(len(running_nfs.values()[i])) / sumlen
  while ratio < p:
    i += 1
    ratio += float((i+1)*len(running_nfs.values()[i])) / sumlen
  nf = random.choice(running_nfs.values()[i])
  if reduce(lambda a,b: a and b, [v in nfs_this_sc for v
                                  in running_nfs.values()[i]]):
    # failing to add a VNF due to this criteria infuences the provided
    # vnf_sharing_probabilty, but it is estimated to be insignificant,
    # otherwise the generation can run into infinite loop!
    log.warn("All the VNF-s of the subchain selected for VNF sharing are"
             " already in the current chain under construction! Skipping"
             " VNF sharing...")
    return False, None
  else:
    while nf in nfs_this_sc:
      nf = random.choice(running_nfs.values()[i])
  if nf in nffg.nfs:
    return False, nf
  else:
    nffg.add_node(nf)
    return True, nf

def generateRequestForCarrierTopo(test_lvl, all_saps_beginning,
                                  all_saps_ending,
                                  running_nfs, loops=False,
                                  use_saps_once=True,
                                  vnf_sharing_probabilty=0.0,
                                  vnf_sharing_same_sg=0.0,
                                  shareable_sg_count=9999999999999999,
                                  multiSC=False, max_sc_count=2):
  """
  By default generates VNF-disjoint SC-s starting/ending only once in each SAP.
  With the 'loops' option, only loop SC-s are generated.
  'vnf_sharing_probabilty' determines the ratio of
     #(VNF-s used by at least two SC-s)/#(not shared VNF-s).
  NOTE: some kind of periodicity is included to make the effect of batching
  visible. But it is (and must be) independent of the batch_length.
  """
  chain_maxlen = 6
  sc_count=1
  # maximal possible bandwidth for chains
  max_bw = 7.0
  if multiSC:
    sc_count = random.randint(2,max_sc_count)
  while len(all_saps_ending) > sc_count and len(all_saps_beginning) > sc_count:
    nffg = NFFG(id="Benchmark-Req-"+str(test_lvl)+"-Piece")
    # newly added NF-s of one request
    current_nfs = []
    for scid in xrange(0,sc_count):
      # find two SAP-s for chain ends.
      nfs_this_sc = []
      sap1 = nffg.add_sap(id = all_saps_beginning.pop() if use_saps_once else \
                          random.choice(all_saps_beginning))
      sap2 = None
      if loops:
        sap2 = sap1
      else:
        tmpid = all_saps_ending.pop() if use_saps_once else \
                random.choice(all_saps_ending)
        while True:
          if tmpid != sap1.id:
            sap2 = nffg.add_sap(id = tmpid)
            break
          else:
            tmpid = all_saps_ending.pop() if use_saps_once else \
                    random.choice(all_saps_ending)
      sg_path = []
      sap1port = sap1.add_port()
      last_req_port = sap1port
      # generate some VNF-s connecting the two SAP-s
      vnf_cnt = next(gen_seq()) % chain_maxlen + 1
      for vnf in xrange(0, vnf_cnt):
        # in the first case p is used to determine which previous chain should
        # be used to share the VNF, in the latter case it is used to determine
        # whether we should share now.
        vnf_added = False
        p = random.random()
        if random.random() < vnf_sharing_probabilty and len(running_nfs) > 0 \
           and not multiSC:
          vnf_added, nf = _shareVNFFromEarlierSG(nffg, running_nfs, nfs_this_sc,
                                                 p)
        elif multiSC and \
             p < vnf_sharing_probabilty and len(current_nfs) > 0 \
             and len(running_nfs) > 0:
          # this influences the the given VNF sharing probability...
          if reduce(lambda a,b: a and b, [v in nfs_this_sc for
                                          v in current_nfs]):
            log.warn("All shareable VNF-s are already added to this chain! "
                     "Skipping VNF sharing...")
          elif random.random() < vnf_sharing_same_sg:
            nf = random.choice(current_nfs)
            while nf in nfs_this_sc:
              nf = random.choice(current_nfs)
            # the VNF is already in the subchain, we just need to add the links
            # vnf_added = True
          else:
            # this happens when VNF sharing is needed but not with the actual SG
            vnf_added, nf = _shareVNFFromEarlierSG(nffg, running_nfs,
                                                   nfs_this_sc, p)
        else:
          nf = nffg.add_nf(id="-".join(("Test",str(test_lvl),"SC",str(scid),
                                        "VNF",str(vnf))),
                           func_type=random.choice(['A','B','C']),
                           cpu=random.randint(1 + \
                                      (2*(test_lvl%4) if test_lvl%4 > 1 else 0),
                                              4 + \
                                      (3*(test_lvl%4) if test_lvl%4 > 1 else 0)),
                           mem=random.random()*1000 + \
                           (1000*(test_lvl%4) if test_lvl%4 > 1 else 0),
                           storage=random.random()*3 + \
                           (6*(test_lvl%4) if test_lvl%4 > 1 else 0),
                           delay=1 + random.random()*10,
                           bandwidth=random.random())
          vnf_added = True
        if vnf_added:
          # add olny the newly added VNF-s, not the shared ones.
          nfs_this_sc.append(nf)
          newport = nf.add_port()
          sglink = nffg.add_sglink(last_req_port, newport)
          sg_path.append(sglink.id)
          last_req_port = nf.add_port()

      sap2port = sap2.add_port()
      sglink = nffg.add_sglink(last_req_port, sap2port)
      sg_path.append(sglink.id)

      # WARNING: this is completly a wild guess! Failing due to this doesn't
      # necessarily mean algorithm failure
      # Bandwidth maximal random value should be min(SAP1acces_bw, SAP2access_bw)
      # MAYBE: each SAP can only be once in the reqgraph? - this is the case now.
      if multiSC:
        minlat = 5.0 * (len(nfs_this_sc) + 2)
        maxlat = 13.0 * (len(nfs_this_sc) + 2)
      else:
        # nfcnt = len([i for i in nffg.nfs])
        minlat = 40.0 - 10.0*(test_lvl%4)
        maxlat = 50.0 - 10.0*(test_lvl%4)
      nffg.add_req(sap1port, sap2port, delay=random.uniform(minlat,maxlat),
                   bandwidth=random.random()*(max_bw + 2*(test_lvl%4)),
                   sg_path = sg_path)
      log.info("Service Chain on NF-s added: %s"%[nf.id for nf in nfs_this_sc])
      # this prevents loops in the chains and makes new and old NF-s equally
      # preferable in total for NF sharing
      new_nfs = [vnf for vnf in nfs_this_sc if vnf not in current_nfs]
      for tmp in xrange(0, scid+1):
        current_nfs.extend(new_nfs)
      if not multiSC:
        return nffg, all_saps_beginning, all_saps_ending
    if multiSC:
      return nffg, all_saps_beginning, all_saps_ending
  return None, all_saps_beginning, all_saps_ending

def StressTestCore(seed, loops, use_saps_once, vnf_sharing, multiple_scs,
                   max_sc_count, vnf_sharing_same_sg, fullremap,
                   batch_length, shareable_sg_count, sliding_share,
                   bw_factor, res_factor, lat_factor, bt_limit, bt_br_factor,
                   outputfile, queue=None, shortest_paths_precalc=None,
                   filehandler=None):
  """
  If queue is given, the result will be put in that Queue object too. Meanwhile
  if shortest_paths_precalc is not given, it means the caller needs the
  shortest_paths, so we send it back. In this case the resulting test_lvl will
  be sent by the queue.
  NOTE: outputfile is only used inside the function if an exception is thrown
  and than it is logged there.
  """
  total_vnf_count = 0
  mapped_vnf_count = 0
  network = CarrierTopoBuilder.getPicoTopo()
  max_test_lvl = 50000
  test_lvl = 1
  all_saps_ending = [s.id for s in network.saps]
  all_saps_beginning = [s.id for s in network.saps]
  running_nfs = OrderedDict()
  random.seed(0)
  random.jumpahead(seed)
  random.shuffle(all_saps_beginning)
  random.shuffle(all_saps_ending)
  shortest_paths = shortest_paths_precalc
  ppid_pid = ""
  # log.addHandler(logging.StreamHandler())
  log.setLevel(logging.WARN)
  if filehandler is not None:
    log.addHandler(filehandler)
  if shortest_paths is not None and type(shortest_paths) != dict:
    excp = Exception("StressTest received something else other than shortest_"
                    "paths dictionary: %s"%type(shortest_paths))
    if queue is not None:
      queue.put(excp)
    raise excp
  if queue is not None:
    ppid_pid = "%s.%s:"%(os.getppid(), os.getpid())

  try:
    try:
      batch_count = 0
      batched_request = NFFG(id="Benchmark-Req-"+str(test_lvl))
      # built-in libs can change the state of random module during mapping.
      random_state = None
      while batched_request is not None:
        if test_lvl > max_test_lvl:
          break
        if (len(all_saps_ending) < batch_length or \
            len(all_saps_beginning) < batch_length) and use_saps_once:
          log.warn("Can't start batching because all SAPs should only be used"
                   " once for SC origin and destination and there are not "
                   "enough SAPs!")
          batched_request = None
        elif batch_count < batch_length:
          request, all_saps_beginning, all_saps_ending = \
                   generateRequestForCarrierTopo(test_lvl, all_saps_beginning,
                                                 all_saps_ending, running_nfs,
                   loops=loops, use_saps_once=use_saps_once,
                   vnf_sharing_probabilty=vnf_sharing,
                   vnf_sharing_same_sg=vnf_sharing_same_sg,
                   multiSC=multiple_scs, max_sc_count=max_sc_count)
          if request is None:
            break
          else:
            batch_count += 1
            running_nfs[test_lvl] = [nf for nf in request.nfs
                                     if nf.id.split("-")[1] == str(test_lvl)]

            # using merge to create the union of the NFFG-s!
            batched_request = NFFGToolBox.merge_nffgs(batched_request,
                                                      request)

            if len(running_nfs) > shareable_sg_count:
              # make the ordered dict function as FIFO
              running_nfs.popitem(last=False)
            test_lvl += 1
            if not sliding_share and test_lvl % shareable_sg_count == 0:
              running_nfs = OrderedDict()
            log.debug("Batching Service Graph number %s..."%batch_count)
        else:
          batch_count = 0
          total_vnf_count += len([nf for nf in batched_request.nfs])
          random_state = random.getstate()
          network, shortest_paths = MappingAlgorithms.MAP(batched_request, network,
                  full_remap=fullremap, enable_shortest_path_cache=True,
                  bw_factor=bw_factor, res_factor=res_factor,
                  lat_factor=lat_factor, shortest_paths=shortest_paths,
                  return_dist=True,
                  bt_limit=bt_limit, bt_branching_factor=bt_br_factor)
          log.debug(ppid_pid+"Mapping successful on test level %s with batch"
                    " length %s!"%(test_lvl, batch_length))
          random.setstate(random_state)
          mapped_vnf_count += len([nf for nf in batched_request.nfs])
          batched_request = NFFG(id="Benchmark-Req-"+str(test_lvl))

    except uet.MappingException as me:
      log.info(ppid_pid+"Mapping failed: %s"%me.msg)
      if not me.backtrack_possible:
        # NOTE: peak SC count is only corret to add to test_lvl if SC-s are
        # disjoint on VNFs.
        log.warn("Peak mapped VNF count is %s in the last run, test level: %s"%
                 (me.peak_mapped_vnf_count,
                  test_lvl - batch_length + me.peak_sc_cnt))
        mapped_vnf_count += me.peak_mapped_vnf_count
        log.warn("All-time peak mapped VNF count: %s, All-time total VNF "
                 "count %s, Acceptance ratio: %s"%(mapped_vnf_count,
                 total_vnf_count, float(mapped_vnf_count)/total_vnf_count))
      # break
    if request is None or batched_request is None:
      log.warn(ppid_pid+"Request generation reached its end!")
      # break

  except uet.UnifyException as ue:
    log.error(ppid_pid+ue.msg)
    log.error(ppid_pid+traceback.format_exc())
    with open(outputfile, "a") as f:
      f.write("\n".join(("UnifyException cought during StressTest: ",
                         ue.msg,traceback.format_exc())))
    if queue is not None:
      queue.put(str(ue.__class__))
      return test_lvl-1
  except Exception as e:
    log.error(ppid_pid+traceback.format_exc())
    with open(outputfile, "a") as f:
      f.write("\n".join(("Exception cought during StressTest: ",
                         traceback.format_exc())))
    if queue is not None:
      queue.put(str(e.__class__))
      return test_lvl-1
  # put the result to the queue
  if queue is not None:
    log.info(ppid_pid+"Putting %s to communication queue"%(test_lvl-1))
    queue.put(test_lvl-1)
    if shortest_paths_precalc is None:
      log.info(ppid_pid+"Returning shortest_paths!")
      return shortest_paths
  # if returned_test_lvl is 0, we failed at the very fist mapping!
  return test_lvl-1

def main(argv):
  try:
    opts, args = getopt.getopt(argv,"ho:",["loops", "fullremap", "bw_factor=",
                               "res_factor=", "lat_factor=", "request_seed=",
                               "vnf_sharing=", "multiple_scs",
                               "vnf_sharing_same_sg=", "max_sc_count=",
                               "shareable_sg_count=", "batch_length=",
                               "bt_br_factor=", "bt_limit=",
                               "sliding_share", "use_saps_once"])
  except getopt.GetoptError:
    print helpmsg
    sys.exit()
  loops = False
  fullremap = False
  vnf_sharing = 0.0
  vnf_sharing_same_sg = 0.0
  seed = 3
  bw_factor = 1
  res_factor = 1
  lat_factor = 1
  outputfile = "paramsearch.out"
  multiple_scs = False
  sliding_share = False
  use_saps_once = False
  max_sc_count = 2
  shareable_sg_count = 99999999999999
  batch_length = 1
  bt_br_factor = 6
  bt_limit = 3
  for opt, arg in opts:
    if opt == '-h':
      print helpmsg
      sys.exit()
    elif opt == '-o':
      outputfile = arg
    elif opt == "--loops":
      loops = True
    elif opt == "--fullremap":
      fullremap = True
    elif opt == "--request_seed":
      seed = int(arg)
    elif opt == "--vnf_sharing":
      vnf_sharing = float(arg)
    elif opt == "--bw_factor":
      bw_factor = float(arg)
    elif opt == "--res_factor":
      res_factor = float(arg)
    elif opt == "--lat_factor":
      lat_factor = float(arg)
    elif opt == "--multiple_scs":
      multiple_scs = True
    elif opt == "--max_sc_count":
      max_sc_count = int(arg)
    elif opt == "--vnf_sharing_same_sg":
      vnf_sharing_same_sg = float(arg)
    elif opt == "--shareable_sg_count":
      shareable_sg_count = int(arg)
    elif opt == "--batch_length":
      batch_length = int(arg)
    elif opt == "--sliding_share":
      sliding_share = True
    elif opt == "--use_saps_once":
      use_saps_once = True
    elif opt == "--bt_limit":
      bt_limit = int(arg)
    elif opt == "--bt_br_factor":
      bt_br_factor = int(arg)
  params, args = zip(*opts)
  if "--bw_factor" not in params or "--res_factor" not in params or \
     "--lat_factor" not in params:
    print helpmsg
    raise Exception("Not all algorithm params are given!")

  returned_test_lvl = StressTestCore(seed, loops, use_saps_once, vnf_sharing,
           multiple_scs, max_sc_count, vnf_sharing_same_sg, fullremap,
           batch_length, shareable_sg_count, sliding_share,
           bw_factor, res_factor, lat_factor, bt_limit, bt_br_factor, outputfile)

  log.info("First unsuccessful mapping was at %s test level."%
           (returned_test_lvl+1))
  if returned_test_lvl > 0:
    with open(outputfile, "a") as f:
      f.write("\nLast successful mapping was at %s test level.\n"%
              (returned_test_lvl))
  else:
    with open(outputfile, "a") as f:
      f.write("\nMapping failed at starting test level (%s)\n"%(returned_test_lvl+1))

if __name__ == '__main__':
  main(sys.argv[1:])


text:
import {ApplicationRef, COMPILER_OPTIONS, Component, destroyPlatform, NgModule, NgZone, TestabilityRegistry, ViewEncapsulation} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {onlyInIvy, withBody} from '@angular/private/testing';

describe('bootstrap', () => {
  beforeEach(destroyPlatform);
  afterEach(destroyPlatform);

  it('should bootstrap using #id selector',
     withBody('
before|
<button id="my-app"></button>', async () => {
       try {
         const ngModuleRef = await platformBrowserDynamic().bootstrapModule(IdSelectorAppModule);
         expect(document.body.textContent).toEqual('before|works!');
         ngModuleRef.destroy();
       } catch (err) {
         console.error(err);
       }
     }));

  it('should bootstrap using one of selectors from the list',
     withBody('
before|

', async () => {
       try {
         const ngModuleRef =
             await platformBrowserDynamic().bootstrapModule(MultipleSelectorsAppModule);
         expect(document.body.textContent).toEqual('before|works!');
         ngModuleRef.destroy();
       } catch (err) {
         console.error(err);
       }
     }));

  describe('options', () => {
    function createComponentAndModule(
        options:
            {encapsulation?: ViewEncapsulation; preserveWhitespaces?: boolean;
             selector?: string} = {}) {
      @Component({
        selector: options.selector || 'my-app',
        styles: [''],
        template: 'a    b',
        encapsulation: options.encapsulation,
        preserveWhitespaces: options.preserveWhitespaces,
        jit: true,
      })
      class TestComponent {
      }

      @NgModule({
        imports: [BrowserModule],
        declarations: [TestComponent],
        bootstrap: [TestComponent],
        jit: true,
      })
      class TestModule {
      }

      return TestModule;
    }

    it('should use ViewEncapsulation.Emulated as default',
       withBody('<my-app></my-app>', async () => {
         const TestModule = createComponentAndModule();

         const ngModuleRef = await platformBrowserDynamic().bootstrapModule(TestModule);
         expect(document.body.innerHTML).toContain('<span _ngcontent-');
         ngModuleRef.destroy();
       }));

    it('should allow setting defaultEncapsulation using bootstrap option',
       withBody('<my-app></my-app>', async () => {
         const TestModule = createComponentAndModule();

         const ngModuleRef = await platformBrowserDynamic().bootstrapModule(
             TestModule, {defaultEncapsulation: ViewEncapsulation.None});
         expect(document.body.innerHTML).toContain('');
         expect(document.body.innerHTML).not.toContain('_ngcontent-');
         ngModuleRef.destroy();
       }));

    it('should allow setting defaultEncapsulation using compiler option',
       withBody('<my-app></my-app>', async () => {
         const TestModule = createComponentAndModule();

         const ngModuleRef = await platformBrowserDynamic([{
                               provide: COMPILER_OPTIONS,
                               useValue: {defaultEncapsulation: ViewEncapsulation.None},
                               multi: true
                             }]).bootstrapModule(TestModule);
         expect(document.body.innerHTML).toContain('');
         expect(document.body.innerHTML).not.toContain('_ngcontent-');
         ngModuleRef.destroy();
       }));

    it('should prefer encapsulation on component over bootstrap option',
       withBody('<my-app></my-app>', async () => {
         const TestModule = createComponentAndModule({encapsulation: ViewEncapsulation.Emulated});

         const ngModuleRef = await platformBrowserDynamic().bootstrapModule(
             TestModule, {defaultEncapsulation: ViewEncapsulation.None});
         expect(document.body.innerHTML).toContain('<span _ngcontent-');
         ngModuleRef.destroy();
       }));

    it('should use preserveWhitespaces: false as default',
       withBody('<my-app></my-app>', async () => {
         const TestModule = createComponentAndModule();

         const ngModuleRef = await platformBrowserDynamic().bootstrapModule(TestModule);
         expect(document.body.innerHTML).toContain('a b');
         ngModuleRef.destroy();
       }));

    it('should allow setting preserveWhitespaces using bootstrap option',
       withBody('<my-app></my-app>', async () => {
         const TestModule = createComponentAndModule();

         const ngModuleRef = await platformBrowserDynamic().bootstrapModule(
             TestModule, {preserveWhitespaces: true});
         expect(document.body.innerHTML).toContain('a    b');
         ngModuleRef.destroy();
       }));

    it('should allow setting preserveWhitespaces using compiler option',
       withBody('<my-app></my-app>', async () => {
         const TestModule = createComponentAndModule();

         const ngModuleRef =
             await platformBrowserDynamic([
               {provide: COMPILER_OPTIONS, useValue: {preserveWhitespaces: true}, multi: true}
             ]).bootstrapModule(TestModule);
         expect(document.body.innerHTML).toContain('a    b');
         ngModuleRef.destroy();
       }));

    it('should prefer preserveWhitespaces on component over bootstrap option',
       withBody('<my-app></my-app>', async () => {
         const TestModule = createComponentAndModule({preserveWhitespaces: false});

         const ngModuleRef = await platformBrowserDynamic().bootstrapModule(
             TestModule, {preserveWhitespaces: true});
         expect(document.body.innerHTML).toContain('a b');
         ngModuleRef.destroy();
       }));

    describe('ApplicationRef cleanup', () => {
      it('should cleanup ApplicationRef when Injector is destroyed',
         withBody('<my-app></my-app>', async () => {
           const TestModule = createComponentAndModule();

           const ngModuleRef = await platformBrowserDynamic().bootstrapModule(TestModule);
           const appRef = ngModuleRef.injector.get(ApplicationRef);
           const testabilityRegistry = ngModuleRef.injector.get(TestabilityRegistry);

           expect(appRef.components.length).toBe(1);
           expect(testabilityRegistry.getAllRootElements().length).toBe(1);

           ngModuleRef.destroy();  // also destroys an Injector instance.

           expect(appRef.components.length).toBe(0);
           expect(testabilityRegistry.getAllRootElements().length).toBe(0);
         }));

      it('should cleanup ApplicationRef when ComponentRef is destroyed',
         withBody('<my-app></my-app>', async () => {
           const TestModule = createComponentAndModule();

           const ngModuleRef = await platformBrowserDynamic().bootstrapModule(TestModule);
           const appRef = ngModuleRef.injector.get(ApplicationRef);
           const testabilityRegistry = ngModuleRef.injector.get(TestabilityRegistry);
           const componentRef = appRef.components[0];

           expect(appRef.components.length).toBe(1);
           expect(testabilityRegistry.getAllRootElements().length).toBe(1);

           componentRef.destroy();

           expect(appRef.components.length).toBe(0);
           expect(testabilityRegistry.getAllRootElements().length).toBe(0);
         }));

      it('should not throw in case ComponentRef is destroyed and Injector is destroyed after that',
         withBody('<my-app></my-app>', async () => {
           const TestModule = createComponentAndModule();

           const ngModuleRef = await platformBrowserDynamic().bootstrapModule(TestModule);
           const appRef = ngModuleRef.injector.get(ApplicationRef);
           const testabilityRegistry = ngModuleRef.injector.get(TestabilityRegistry);
           const componentRef = appRef.components[0];

           expect(appRef.components.length).toBe(1);
           expect(testabilityRegistry.getAllRootElements().length).toBe(1);

           componentRef.destroy();
           ngModuleRef.destroy();  // also destroys an Injector instance.

           expect(appRef.components.length).toBe(0);
           expect(testabilityRegistry.getAllRootElements().length).toBe(0);
         }));

      it('should not throw in case Injector is destroyed and ComponentRef is destroyed after that',
         withBody('<my-app></my-app>', async () => {
           const TestModule = createComponentAndModule();

           const ngModuleRef = await platformBrowserDynamic().bootstrapModule(TestModule);
           const appRef = ngModuleRef.injector.get(ApplicationRef);
           const testabilityRegistry = ngModuleRef.injector.get(TestabilityRegistry);
           const componentRef = appRef.components[0];

           expect(appRef.components.length).toBe(1);
           expect(testabilityRegistry.getAllRootElements().length).toBe(1);

           ngModuleRef.destroy();  // also destroys an Injector instance.
           componentRef.destroy();

           expect(appRef.components.length).toBe(0);
           expect(testabilityRegistry.getAllRootElements().length).toBe(0);
         }));
    });

    describe('PlatformRef cleanup', () => {
      it('should unsubscribe from `onError` when Injector is destroyed',
         withBody('<my-app></my-app>', async () => {
           const TestModule = createComponentAndModule();

           const ngModuleRef = await platformBrowserDynamic().bootstrapModule(TestModule);
           const ngZone = ngModuleRef.injector.get(NgZone);

           expect(ngZone.onError.observers.length).toBe(1);

           ngModuleRef.destroy();

           expect(ngZone.onError.observers.length).toBe(0);
         }));
    });

    onlyInIvy('options cannot be changed in Ivy').describe('changing bootstrap options', () => {
      beforeEach(() => {
        spyOn(console, 'error');
      });

      it('should log an error when changing defaultEncapsulation bootstrap options',
         withBody('<my-app-a></my-app-a><my-app-b></my-app-b>', async () => {
           const platformRef = platformBrowserDynamic();

           const TestModuleA = createComponentAndModule({selector: 'my-app-a'});
           const ngModuleRefA = await platformRef.bootstrapModule(
               TestModuleA, {defaultEncapsulation: ViewEncapsulation.None});
           ngModuleRefA.destroy();

           const TestModuleB = createComponentAndModule({selector: 'my-app-b'});
           const ngModuleRefB = await platformRef.bootstrapModule(
               TestModuleB, {defaultEncapsulation: ViewEncapsulation.ShadowDom});
           expect(console.error)
               .toHaveBeenCalledWith(
                   'Provided value for `defaultEncapsulation` can not be changed once it has been set.');

           // The options should not have been changed
           expect(document.body.innerHTML).not.toContain('_ngcontent-');

           ngModuleRefB.destroy();
         }));

      it('should log an error when changing preserveWhitespaces bootstrap options',
         withBody('<my-app-a></my-app-a><my-app-b></my-app-b>', async () => {
           const platformRef = platformBrowserDynamic();

           const TestModuleA = createComponentAndModule({selector: 'my-app-a'});
           const ngModuleRefA =
               await platformRef.bootstrapModule(TestModuleA, {preserveWhitespaces: true});
           ngModuleRefA.destroy();

           const TestModuleB = createComponentAndModule({selector: 'my-app-b'});
           const ngModuleRefB =
               await platformRef.bootstrapModule(TestModuleB, {preserveWhitespaces: false});
           expect(console.error)
               .toHaveBeenCalledWith(
                   'Provided value for `preserveWhitespaces` can not be changed once it has been set.');

           // The options should not have been changed
           expect(document.body.innerHTML).toContain('a    b');

           ngModuleRefB.destroy();
         }));

      it('should log an error when changing defaultEncapsulation to its default',
         withBody('<my-app-a></my-app-a><my-app-b></my-app-b>', async () => {
           const platformRef = platformBrowserDynamic();

           const TestModuleA = createComponentAndModule({selector: 'my-app-a'});
           const ngModuleRefA = await platformRef.bootstrapModule(TestModuleA);
           ngModuleRefA.destroy();

           const TestModuleB = createComponentAndModule({selector: 'my-app-b'});
           const ngModuleRefB = await platformRef.bootstrapModule(
               TestModuleB, {defaultEncapsulation: ViewEncapsulation.Emulated});
           // Although the configured value may be identical to the default, the provided set of
           // options has still been changed compared to the previously provided options.
           expect(console.error)
               .toHaveBeenCalledWith(
                   'Provided value for `defaultEncapsulation` can not be changed once it has been set.');

           ngModuleRefB.destroy();
         }));

      it('should log an error when changing preserveWhitespaces to its default',
         withBody('<my-app-a></my-app-a><my-app-b></my-app-b>', async () => {
           const platformRef = platformBrowserDynamic();

           const TestModuleA = createComponentAndModule({selector: 'my-app-a'});
           const ngModuleRefA = await platformRef.bootstrapModule(TestModuleA);
           ngModuleRefA.destroy();

           const TestModuleB = createComponentAndModule({selector: 'my-app-b'});
           const ngModuleRefB =
               await platformRef.bootstrapModule(TestModuleB, {preserveWhitespaces: false});
           // Although the configured value may be identical to the default, the provided set of
           // options has still been changed compared to the previously provided options.
           expect(console.error)
               .toHaveBeenCalledWith(
                   'Provided value for `preserveWhitespaces` can not be changed once it has been set.');

           ngModuleRefB.destroy();
         }));

      it('should not log an error when passing identical bootstrap options',
         withBody('<my-app-a></my-app-a><my-app-b></my-app-b>', async () => {
           const platformRef = platformBrowserDynamic();

           const TestModuleA = createComponentAndModule({selector: 'my-app-a'});
           const ngModuleRefA = await platformRef.bootstrapModule(
               TestModuleA,
               {defaultEncapsulation: ViewEncapsulation.None, preserveWhitespaces: true});
           ngModuleRefA.destroy();

           // Bootstrapping multiple modules using the exact same options should be allowed.
           const TestModuleB = createComponentAndModule({selector: 'my-app-b'});
           const ngModuleRefB = await platformRef.bootstrapModule(
               TestModuleB,
               {defaultEncapsulation: ViewEncapsulation.None, preserveWhitespaces: true});
           ngModuleRefB.destroy();
         }));
    });
  });
});

@Component({
  selector: '#my-app',
  template: 'works!',
})
export class IdSelectorAppComponent {
}

@NgModule({
  imports: [BrowserModule],
  declarations: [IdSelectorAppComponent],
  bootstrap: [IdSelectorAppComponent],
})
export class IdSelectorAppModule {
}

@Component({
  selector: '[foo],span,.bar',
  template: 'works!',
})
export class MultipleSelectorsAppComponent {
}

@NgModule({
  imports: [BrowserModule],
  declarations: [MultipleSelectorsAppComponent],
  bootstrap: [MultipleSelectorsAppComponent],
})
export class MultipleSelectorsAppModule {
}

redpajama_set_name: RedPajamaGithub


text:
MODULE_ALWAYS(youtube);

#define NETHER_COUNT   7000
#define NETHER_VICTIM "graphite"

typedef struct {
    const char *user;
    const char *chan;
    int         count;
    int         timestamp;
} youtube_t;

static bool youtube_find(const char *id, youtube_t *data) {
    database_statement_t *check = database_statement_create("SELECT AUTHOR, CHANNEL, TIMESTAMP, COUNT FROM YOUTUBE WHERE ID = ?");
    if (!database_statement_bind(check, "s", id))
        return false;

    database_row_t *row = database_row_extract(check, "ssii");
    if (!row)
        return false;

    data->user      = database_row_pop_string(row);
    data->chan      = database_row_pop_string(row);
    data->timestamp = database_row_pop_integer(row);
    data->count     = database_row_pop_integer(row);

    if (!database_statement_complete(check))
        return false;
    return true;
}

static bool youtube_update(const char *id, youtube_t *data) {
    data->count++;
    database_statement_t *update = database_statement_create("UPDATE YOUTUBE SET COUNT = ?, AUTHOR = ?, TIMESTAMP = ? WHERE ID = ?");
    if (!database_statement_bind(update, "isis", data->count, data->user, data->timestamp, id))
        return false;
    if (!database_statement_complete(update))
        return false;
    return true;
}

static bool youtube_add(const char *id, youtube_t *data) {
    database_statement_t *add = database_statement_create("INSERT INTO YOUTUBE VALUES(?, ?, ?, ?, ?)");
    if (!database_statement_bind(add, "sssii", data->user, data->chan, id, data->timestamp, data->count))
        return false;
    if (!database_statement_complete(add))
        return false;
    return true;
}

static int youtube_count(void) {
    database_statement_t *count = database_statement_create("SELECT SUM(COUNT) FROM YOUTUBE");
    if (!count)
        return 0;
    database_row_t *row = database_row_extract(count, "i");
    if (!row)
        return 0;
    return database_row_pop_integer(row);
}

void module_enter(irc_t *irc, const char *channel, const char *user, const char *message) {
    if (!message)
        return;

    if (strstr(message, "-stats") == &message[0])
        goto last;

    regexpr_t *regex = regexpr_create("(https?://)?(www\\.)?youtu(\\.be/|be\\.com/watch.*[?&]v=)([^&]+)", false);
    if (!regex)
        return;

    regexpr_match_t *matches;
    if (!regexpr_execute(regex, message, 5, &matches))
        return;

    regexpr_match_t videoid = matches[4];
    if (regexpr_match_invalid(videoid))
        return;

    char *id = strdup(message);
    id += videoid.soff;
    id[videoid.eoff - videoid.soff] = '\0';

    youtube_t data;
    if (youtube_find(id, &data)) {
        irc_write(irc, channel,
            "%s: I've seen that youtube link %d %s before, last was %s by %s on %s",
            user,
            data.count,
            (data.count == 1)
                ? "time"
                : "times",
            strdur(time(NULL) - data.timestamp),
            data.user,
            (!strcmp(data.chan, channel))
                ? "this channel"
                : data.chan
        );
        data.user      = user;
        data.timestamp = time(NULL);
        youtube_update(id, &data);
    } else {
        data.user      = user;
        data.count     = 1;
        data.timestamp = time(NULL);
        data.chan      = channel;

        youtube_add(id, &data);
    }

    int count;
last:
    count = youtube_count();
    irc_write(irc, channel,
        "%s: A total of %d %s been spammed in my presence, only %d more to go until %s waxes his nethers.",
        user,
        count,
        (count == 1)
            ? "link has"
            : "links have",
        NETHER_COUNT - count,
        NETHER_VICTIM
    );
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>Jasmine Test Runner</title>
    <link rel="stylesheet" type="text/css" href="lib/jasmine.css">
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.min.js"></script>
    <script type="text/javascript" src="lib/jasmine.js"></script>
    <script type="text/javascript" src="lib/jasmine-html.js"></script>
    <script type="text/javascript" src="lib/jasmine-jquery-1.1.2.js"></script>
    <script type="text/javascript" src="lib/jquery.simulate.js"></script>

    <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script type="text/javascript" src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js"></script>
    <script type="text/javascript" src="dist/js/multiselect.min.js"></script>

    <!-- include spec files here... -->
    <script type="text/javascript" src="spec/zero-configuration.spec.js"></script>
    <script type="text/javascript" src="spec/data-options.spec.js"></script>
    <script type="text/javascript" src="spec/javascript-options.spec.js"></script>
    <script type="text/javascript" src="spec/search.spec.js"></script>
    <script type="text/javascript" src="spec/keep-rendering-sort.spec.js"></script>
    <script type="text/javascript" src="spec/undo-redo.spec.js"></script>
    <script type="text/javascript" src="spec/multiple-destinations.spec.js"></script>
</head>
<body>

<script type="text/javascript">
    jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
    jasmine.getEnv().execute();
</script>

</body>
</html>


text:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Chronological.QueryResults.Aggregates
{
    public class AggregateQueryResultAggregateJsonConverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        private List<AggregateQueryMeasure> GetMeasures(JArray measuresJArray)
        {
            var measures = new List<AggregateQueryMeasure>();

            foreach (var item in measuresJArray)
            {
                var measure = new AggregateQueryMeasure();
                if (item is JArray)
                {
                    measure.Measures = GetMeasures((JArray) item);
                }
                else
                {
                    measure.Measure = ((JValue)item).ToObject<double?>();
                }
                measures.Add(measure);
            }

            return measures;
        }

        private List<AggregateQueryResultAggregate> GetAggregates(JArray aggregatesJArray)
        {
            var aggregates = new List<AggregateQueryResultAggregate>();

            foreach (var item in aggregatesJArray)
            {
                var aggregate = GetAggregate((JObject) item);
                aggregates.Add(aggregate);
            }

            return aggregates;
        }

        private AggregateQueryResultAggregate GetAggregate(JObject aggregateJObject)
        {
            var aggregateResult = new AggregateQueryResultAggregate();
            //aggregateResult.Dimension = aggregateJObject["dimension"].ToObject<List<string>>();
            var dimensionJArray = (JArray) aggregateJObject["dimension"];
            aggregateResult.Dimension = new List<string>();
            foreach (var dimension in dimensionJArray)
            {
                string dimensionString;

                if (dimension.Type == JTokenType.Object)
                {
                    // This assumes it is a NumericHistogram
                    dimensionString = $"from: {dimension["from"].Value<string>()}, to: {dimension["to"].Value<string>()}";
                }
                else
                {
                    var dimensionValue = (JValue)dimension;
                    //Temporary conversion back to string to avoid having multiple types for dimension, needs a rethink
                    if (dimensionValue.Type == JTokenType.Date)
                    {
                        dimensionString = ((DateTime) dimensionValue.Value).ToUniversalTime()
                            .ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'");
                    }
                    else
                    {
                        dimensionString = dimensionValue.ToString();
                    }
                }

                aggregateResult.Dimension.Add(dimensionString);
            }
            if (aggregateJObject["measures"] != null)
            {
                var measuresJArray = (JArray)aggregateJObject["measures"];
                var measures = GetMeasures(measuresJArray);
                aggregateResult.Measures = measures;
            }
            if (aggregateJObject["aggregate"] != null)
            {
                var subAggregateJObject = (JObject) aggregateJObject["aggregate"];
                var subAggregate = GetAggregate(subAggregateJObject);
                aggregateResult.Aggregate = subAggregate;
            }
            return aggregateResult;
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var jArray = JArray.Load(reader);
            return GetAggregates(jArray);
        }

        public override bool CanRead => true;

        public override bool CanWrite => false;

        public override bool CanConvert(Type objectType) => false;
    }
}


text:
"""
This module implements a tree builder for html5lib that generates lxml
html element trees.  This module uses camelCase as it follows the
html5lib style guide.
"""

from html5lib.treebuilders import _base, etree as etree_builders
from lxml import html, etree

class DocumentType(object):

    def __init__(self, name, publicId, systemId):
        self.name = name
        self.publicId = publicId
        self.systemId = systemId

class Document(object):

    def __init__(self):
        self._elementTree = None
        self.childNodes = []

    def appendChild(self, element):
        self._elementTree.getroot().addnext(element._element)

class TreeBuilder(_base.TreeBuilder):
    documentClass = Document
    doctypeClass = DocumentType
    elementClass = None
    commentClass = None
    fragmentClass = Document

    def __init__(self):
        html_builder = etree_builders.getETreeModule(html, fullTree=False)
        etree_builder = etree_builders.getETreeModule(etree, fullTree=False)
        self.elementClass = html_builder.Element
        self.commentClass = etree_builder.Comment
        _base.TreeBuilder.__init__(self)

    def reset(self):
        _base.TreeBuilder.reset(self)
        self.rootInserted = False
        self.initialComments = []
        self.doctype = None

    def getDocument(self):
        return self.document._elementTree

    def getFragment(self):
        fragment = []
        element = self.openElements[0]._element
        if element.text:
            fragment.append(element.text)
        fragment.extend(element.getchildren())
        if element.tail:
            fragment.append(element.tail)
        return fragment

    def insertDoctype(self, name, publicId, systemId):
        doctype = self.doctypeClass(name, publicId, systemId)
        self.doctype = doctype

    def insertComment(self, data, parent=None):
        if not self.rootInserted:
            self.initialComments.append(data)
        else:
            _base.TreeBuilder.insertComment(self, data, parent)

    def insertRoot(self, name):
        buf = []
        if self.doctype and self.doctype.name:
            buf.append('<!DOCTYPE %s' % self.doctype.name)
            if self.doctype.publicId is not None or self.doctype.systemId is not None:
                buf.append(' PUBLIC "%s" "%s"' % (self.doctype.publicId,
                                                  self.doctype.systemId))
            buf.append('>')
        buf.append('<html></html>')
        root = html.fromstring(u''.join(buf))

        # Append the initial comments:
        for comment in self.initialComments:
            root.addprevious(etree.Comment(comment))

        # Create the root document and add the ElementTree to it
        self.document = self.documentClass()
        self.document._elementTree = root.getroottree()

        # Add the root element to the internal child/open data structures
        root_element = self.elementClass(name)
        root_element._element = root
        self.document.childNodes.append(root_element)
        self.openElements.append(root_element)

        self.rootInserted = True


text:
CDlgPara::CDlgPara(Parameters &para):_para(para)
{
	setupUi(this);

	QString str = QString("%1").arg(_para.w_ssim);
	lineEdit_SSIM->setText(str);
	str = QString("%1").arg(_para.w_tps);
	lineEdit_TPS->setText(str);
	str = QString("%1").arg(1.0-_para.ssim_clamp);
	lineEdit_SSIMClamp->setText(str);
	str = QString("%1").arg(_para.w_ui);
	lineEdit_UI->setText(str);

	str = QString("%1").arg(_para.max_iter);
	lineEdit_Iter->setText(str);
	str = QString("%1").arg(_para.max_iter_drop_factor);
	lineEdit_Drop->setText(str);
	str = QString("%1").arg(_para.eps);
	lineEdit_EPS->setText(str);

	switch (_para.bcond)
	{
	case BCOND_NONE:
		radioButton_1->setChecked(true);
		break;
	case BCOND_CORNER:
		radioButton_2->setChecked(true);
		break;
	case BCOND_BORDER:
		radioButton_3->setChecked(true);
		break;
	}

	connect(pushButton_Confirm,SIGNAL(clicked()),this,SLOT(onConfirm()));
	connect(pushButton_Cancel,SIGNAL(clicked()),this,SLOT(onCancel()));
}

CDlgPara::~CDlgPara(void)
{

}

void CDlgPara::onConfirm()
{
	QString str = lineEdit_SSIM->text();
	_para.w_ssim=str.toFloat();
	str = lineEdit_TPS->text();
	_para.w_tps=str.toFloat();
	str = lineEdit_UI->text();
	_para.w_ui=str.toFloat();
	str = lineEdit_SSIMClamp->text();
	_para.ssim_clamp=1.0-str.toFloat();
	str = lineEdit_Iter->text();
	_para.max_iter=str.toFloat();
	str = lineEdit_Drop->text();
	_para.max_iter_drop_factor=str.toFloat();
	str = lineEdit_EPS->text();
	_para.eps=str.toFloat();

	if (radioButton_1->isChecked ())
		_para.bcond=BCOND_NONE;
	else if(radioButton_2->isChecked ())
		_para.bcond=BCOND_CORNER;
	else if(radioButton_3->isChecked())
		_para.bcond=BCOND_BORDER;

	emit sigModified();
	close();
}

void CDlgPara::onCancel()
{

	close();
}


text:
<!DOCTYPE html>

    <meta charset="utf-8" />

    <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="HandheldFriendly" content="True" />
<meta name="MobileOptimized" content="320" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

<link rel="apple-touch-icon" sizes="180x180" href="http://dangkhoasdc.github.io//apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="http://dangkhoasdc.github.io//favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="http://dangkhoasdc.github.io//favicon-16x16.png">
<link rel="manifest" href="http://dangkhoasdc.github.io//site.webmanifest">
<link rel="mask-icon" href="http://dangkhoasdc.github.io//safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">

<meta name="keywords" content="">

<meta property="og:title" content="Giới thiệu" />
<meta property="og:description" content="Thanh niên finetune models vào ngày làm việc và về đem nghịch ngợm với 3D model và dev game.
Một số chủ đề mình quan tâm bao gồm:
 Thị Giác Máy Tính (Computer Vision)  Visual Search 1. Multiple View Geometries 2. Object Detection.   Thuật toán (Algorithms) 3. Đồ họa máy tính (Computer Graphics). Thiết kế game (Game Development).    Cuộc đời đưa đẩy khi job đầu tiên mình được làm là về image search." />
<meta property="og:type" content="article" />
<meta property="og:url" content="http://dangkhoasdc.github.io/about/" />
<meta property="og:site_name" content="Blog" />

<meta property="og:site_name" content="Blog" />

<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="Giới thiệu"/>
<meta name="twitter:description" content="Thanh niên finetune models vào ngày làm việc và về đem nghịch ngợm với 3D model và dev game.
Một số chủ đề mình quan tâm bao gồm:
 Thị Giác Máy Tính (Computer Vision)  Visual Search 1. Multiple View Geometries 2. Object Detection.   Thuật toán (Algorithms) 3. Đồ họa máy tính (Computer Graphics). Thiết kế game (Game Development).    Cuộc đời đưa đẩy khi job đầu tiên mình được làm là về image search."/>

<meta itemprop="name" content="Giới thiệu">
<meta itemprop="description" content="Thanh niên finetune models vào ngày làm việc và về đem nghịch ngợm với 3D model và dev game.
Một số chủ đề mình quan tâm bao gồm:
 Thị Giác Máy Tính (Computer Vision)  Visual Search 1. Multiple View Geometries 2. Object Detection.   Thuật toán (Algorithms) 3. Đồ họa máy tính (Computer Graphics). Thiết kế game (Game Development).    Cuộc đời đưa đẩy khi job đầu tiên mình được làm là về image search.">

<meta itemprop="wordCount" content="155">

<meta itemprop="keywords" content="" />

    <title>Giới thiệu || Blog</title>
    <link rel="canonical" href="http://dangkhoasdc.github.io/about/" />

    <link rel="stylesheet" href="/css/reboot.css" />
<link rel="stylesheet" href="/css/style.css" />
<link rel="stylesheet" href="/css/syntax.css" />

<link href="https://fonts.googleapis.com/css?family=Lora&display=swap" rel="stylesheet">

    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
    <link rel="apple-touch-icon" href="/apple-touch-icon.png" />

      /
      Blog

              English version

  <meta itemprop="author" content="" />
  <meta itemprop="publisher" content="" />
  <meta itemprop="image" content="" />

Giới thiệu

  <meta itemprop="headline" content="Giới thiệu" />

Thanh niên finetune models vào ngày làm việc và về đem nghịch ngợm với 3D model và dev game.

Một số chủ đề mình quan tâm bao gồm:

Thị Giác Máy Tính (Computer Vision)

Visual Search 1.

Multiple View Geometries 2.

Object Detection.

Thuật toán (Algorithms) 3.

Đồ họa máy tính (Computer Graphics).

Thiết kế game (Game Development).

Cuộc đời đưa đẩy khi job đầu tiên mình được làm là về image search. Và công ty hiện tại mình đang làm cũng là về image search (mặc dù mình được giao bên detection nhiều hơn). ↩

Hồi cấp 3 mình ngán nhất môn hình học. Thậm chí điểm đại học của mình bị mất 0.25 cũng chỉ vì câu hình học. Tuy nhiên, cuộc đời trôi nổi khiến mình lại gắng bó với nó thêm vài lần nữa. ↩

Một ngày nào đó mình sẽ chi phục được cuốn The Art of Computer Programming. ↩

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.10.2/dist/katex.min.css" integrity="sha384-yFRtMMDnQtDRO8rLpMIKrtPCD5jdktao2TV19YiZYWMDkUR5GQZR/NOVTdquEx1j" crossorigin="anonymous">


text:
import numpy as np
import scipy
from scipy.ndimage.morphology import binary_dilation, binary_erosion
import matplotlib.pyplot as plt

import logging
import sys

def find_peaks(y, thres=0.0, min_dist=1):
    '''Peak detection routine.

    Finds the peaks in *y* by taking its first order difference. By using
    *thres* and *min_dist* parameters, it is possible to reduce the number of
    detected peaks.

    Parameters
    ----------
    y : ndarray
        1D amplitude data to search for peaks.
    thres : float between [0., 1.]
        Normalized threshold. Only the peaks with amplitude higher than the
        threshold will be detected.
    min_dist : int
        Minimum distance between each detected peak. The peak with the highest
        amplitude is preferred to satisfy this constraint.

    Returns
    -------
    ndarray
        Array containing the indexes of the peaks that were detected
    '''
    thres *= np.max(y) - np.min(y)

    # find the peaks by using the first order difference
    dy = np.diff(y)
    peaks = np.where((np.hstack([dy, 0.]) < 0.)
                     & (np.hstack([0., dy]) > 0.)
                     & (y > thres))[0]

    if peaks.size > 1 and min_dist > 1:
        highest = peaks[np.argsort(y[peaks])][::-1]
        rem = np.ones(y.size, dtype=bool)
        rem[peaks] = False

        for peak in highest:
            if not rem[peak]:
                sl = slice(max(0, peak-min_dist), peak+min_dist+1)
                rem[sl] = True
                rem[peak] = False

        peaks = np.arange(y.size)[~rem]

    return peaks

def detectSignal(signal, burn_initial_samples=200, thres = 1e-3):
    ''' Returns indexes of samples that are above the threshold (in terms of magnitude)'''
    t = np.abs(signal) > thres
    t = binary_dilation(t,iterations=200)
    return np.where(t!=0)[0]

def readSamples(filename, maxsize = -1):
    ''' Read samples from file
        The file format is [n0.re, n0.im, n1.re, n1.im, ... ]
    '''
    print 'reading file: {0}'.format(filename)
    dat = np.fromfile(open(filename), dtype=scipy.float32)
    if maxsize == -1:
        maxsize = len(dat)
    dat = dat[:maxsize]
    dat_complex = dat[0::2] + dat[1::2]*1j
    return dat_complex

def writeSamples(filename, samples):
    ''' Write samples to file
        The file format is [n0.re, n0.im, n1.re, n1.im, ... ]
    '''
    print 'writing file: {0}'.format(filename)
    raw_seq = np.vstack([np.real(samples),np.imag(samples)]).T.ravel()
    raw_seq.astype(scipy.float32).tofile(open(filename,'wb'))

def trim_samples(raw_samples, burst_size = 1000, number_of_bursts = 3):

    # Find samples with larger magnitude
    trimmed_samples_id = detectSignal( raw_samples[0][ :max([len(x) for x in raw_samples]) ] )

    # do we really need this?  the selected id should always be in the overlapping part
    trimmed_samples_id = trimmed_samples_id[ trimmed_samples_id < min([x.size for x in raw_samples]) ]

    if( len(trimmed_samples_id) < number_of_bursts*burst_size ):
        logging.error('Number of samples over the signal detection threshold = {0}, Expected at least {1}'.format(len(trimmed_samples_id), number_of_bursts*burst_size ))
        sys.exit(1)

    # Extract samples with larger magnitude
    trimmed_samples = [ x[trimmed_samples_id] for x in raw_samples ]

    # Convolve with a square function to find the exact location of the bursts
    match = np.convolve(np.ones(burst_size), np.abs( trimmed_samples[0] ),mode='valid')
    peaks = find_peaks(match, thres=0, min_dist=burst_size)

    if( len(peaks) != number_of_bursts):
        logging.error('Found {0} bursts\n, Expected {1}'.format( len(peaks), number_of_bursts ))
        sys.exit(1)

    # find the indexes of the samples we want to keep
    mask = np.zeros(match.size); mask[peaks] = 1
    idx = np.convolve(np.ones(burst_size), mask)

    if(sum( idx!=0 ) != burst_size*number_of_bursts):
        logging.error('Number of samples after trimming = {0}\n, Expected {1}'.format(
            sum( idx!=0 ), burst_size*number_of_bursts ))
        sys.exit(1)

    if len( np.unique( [len(x) for x in trimmed_samples]) ) != 1:
        logging.error('Number of samples inconsistent')
        sys.exit(1)

    return [ x[idx!=0] for x in trimmed_samples]

######################################################################################################
# Plot received signals
######################################################################################################

try:
    import argparse
    parser = argparse.ArgumentParser(description='Extract bursts of signals from raw sample files')
    parser.add_argument('--run', type=str, default='0', help='run identifier')
    parser.add_argument('--bursts', type=int, default=2, help='number of bursts in the signal')
    parser.add_argument('--burst_size', type=int, default=1000, help='samples per burst')
    parser.add_argument('--rx', type=int, default=4, help='number of antennas')
    parser.add_argument('--path', type=str, default='/root/aoa/data/', help='path to the data folder')

    args = parser.parse_args()
except:
    args = type('empty_object', (object,), {})()
    args.run = sys.argv[1]
    args.bursts = int(sys.argv[2])
    args.rx = int(sys.argv[3])
    args.burst_size = 1000
    args.path = '/root/aoa/data/'

print 'version 2'

# Read samples from raw data files
raw_samples = [ readSamples(args.path+'rx'+str(rx+1)+'_'+str(args.run)+'.dat') for rx in range(args.rx) ]

print 'measurement length:', [x.size for x in raw_samples]
# Extract the parts that correspond to the bursts
trimmed_samples = trim_samples(raw_samples, burst_size = args.burst_size, number_of_bursts = args.bursts)

for rx in range(args.rx):
    writeSamples(args.path+'trimmed_rx'+str(rx+1)+'_'+str(args.run)+'.dat', trimmed_samples[rx])


text:
import { ShareKnowledge20 } from "../../";

export = ShareKnowledge20;


text:
const i18n = require('..')
const should = require('should')

describe('staticCatalog configuration', () => {
  it('should take locales from static catalog if set', (done) => {
    i18n.configure({
      staticCatalog: {
        en: {}
      }
    })

    const expected = ['en'].sort()
    should.deepEqual(i18n.getLocales(), expected)

    done()
  })

  it('should use static locale definitions from static catalog if set', (done) => {
    i18n.configure({
      staticCatalog: {
        en: {}
      }
    })

    const expected = {}
    should.deepEqual(i18n.getCatalog('en'), expected)

    done()
  })
})


text:
namespace app {
namespace Uno {

::uDelegateType* Action__Outracks_Simulator_Bytecode_IsType__Uno_IO_BinaryWriter__typeof();

}}

#endif


text:
@interface ViewController : UIViewController<UIPickerViewDelegate,UIPickerViewDataSource>
{
    UIView *translateObj;
    UIView *scaleObj;
    UIView *rotateObj;
    float duration;

    UIPickerView *pickerView;

    NSMutableArray *easingList;
    EasingFunction currentEasing;
}

-(void)easeIn:(UIButton*)btn;
-(void)easeOut:(UIButton*)btn;
-(void)easeInOut:(UIButton*)btn;

-(void)doAnimation:(KeyframeParametricBlock)easingFn;
-(EasingFunction)getEaseFn:(NSString*)easeType;

@end


text:
const assert = require('assert');
const moxios = require('moxios');

const {Transport, Resource, Resources} = require('../../src');

describe('Resource', function () {
  let transport;
  beforeEach(function () {
    // import and pass your custom axios instance to this method
    moxios.install();
    transport = new Transport();
  });

  afterEach(function () {
    // import and pass your custom axios instance to this method
    moxios.uninstall();
  });
  it('create new resource', function () {
    const resourceJson = {_id: '123', name: 'X', __v: 0};
    const resources = new Resources(transport);
    const res = resources.create();
    assert.equal(res.isNew, true);
    res.overwrite(resourceJson);
    assert.equal(res.name(), 'X');
    assert.equal(res.id, '123');
    assert.equal(res.isDirty(), true);
  });
  it('resources update', function () {
    const resources = new Resources(transport);
    return resources.update()
      .reflect()
      .then((promise) => {
        assert.equal(promise.isRejected(), true);
      });
  });
  it('constructing with valid json', function () {
    const resourceJson = {_id: '123', name: 'X', __v: 0};
    const res = new Resource(transport, resourceJson);
    assert.equal(res.name(), 'X');
    assert.equal(res.id, '123');
    assert.equal(res.isDirty(), false);
    assert.equal(res.toString(), '123: X');
    assert.deepEqual(res.toJson(), resourceJson);
    assert.deepEqual(res.getChanges(), {});
    assert.deepEqual(res.version, 0);
  });
  it('constructing with invalid json', function () {
    const resourceJson = 'invalid';
    assert.throws(() => new Resource(transport, resourceJson), Error);
  });
  describe('modify', function () {
    it('isDirty if change happen', function () {
      const resourceJson = {_id: '123', name: 'X', __v: 0};
      const res = new Resource(transport, resourceJson);
      res.name('Y');
      assert.deepEqual(res.getChanges(), {name: 'Y'});
      assert.equal(res.isDirty(), true);
    });
    it('possible to change multiple', function () {
      const resourceJson = {_id: '123', name: 'X', __v: 0};
      const res = new Resource(transport, resourceJson);
      assert.equal(res.name('Y').location.site('oulu').name(), 'Y');
      assert.deepEqual(res.getChanges(), {name: 'Y', location: {site: 'oulu'}});
      assert.equal(res.isDirty(), true);
    });
    it('apis', function () {
      const resourceJson = {_id: '123', name: 'X', __v: 0};
      const res = new Resource(transport, resourceJson);
      res.name('Y')
        .type('hw')
        .status.value('available')
        .status.note('hups')
        .status.availability('sure')
        .usage.type('aa')
        .usage.group('group1')
        .location.site('oulu')
        .location.country('finland')
        .location.city('oulu')
        .location.postcode('1234')
        .location.address('street')
        .location.room('a')
        .location.subRoom('b')
        .location.geo(123)
        .location.rack('r1')
        .location.bed('b2')
        .location.slot('s3')
        .item.model('aa')
        .item.ref('1234')
        .network.hostname('local')
        .network.domain('domain')
        .hw.sn('12')
        .hw.imei('34')
        .hw.id('123')
        .hw.firmware.name('q')
        .hw.firmware.version('1')
        .hw.meta_data('a', 'b')
        .parent('123')
        .childs(['987']);
      const changes = {
        name: 'Y',
        type: 'hw',
        status: {
          value: 'available',
          note: 'hups',
          availability: 'sure'
        },
        item: {
          model: 'aa',
          ref: '1234'
        },
        location: {
          site: 'oulu',
          country: 'finland',
          city: 'oulu',
          postcode: '1234',
          address: 'street',
          room: 'a',
          subRoom: 'b',
          rack: 'r1',
          bed: 'b2',
          slot: 's3',
          geo: 123
        },
        usage: {
          type: 'aa',
          group: 'group1'
        },
        network: {
          hostname: 'local',
          domain: 'domain'
        },
        hw: {
          sn: '12',
          imei: '34',
          id: '123',
          firmware: {name: 'q', version: '1'},
          meta_data: {a: 'b'}
        },
        parent: '123',
        childs: ['987']
      };
      assert.deepEqual(res.getChanges(), changes);
      assert.equal(res.isDirty(), true);
    });
  });
  describe('find', function () {
    it('base', function () {
      moxios.stubRequest('/api/v0/resources', {
        status: 200,
        response: []
      });
      const resources = new Resources(transport);
      transport.token = 'abc';
      const find = resources.find();
      return find.exec();
    });
    it('apis', function () {
      const resources = new Resources(transport);
      const find = resources.find()
        .name('abc')
        .id('asd')
        .hwid('abc')
        .hwsn('abc')
        .itemModel('abc')
        .hasParent()
        .hasParent('abc')
        .hasNoParent()
        .type('x')
        .status('active')
        .usageType('manual')
        .haveTag('test')
        .haveTags(['a', 'b']);
      assert.ok(find);
    });
  });
});


text:
/*
 * My Wallet
 * It is a Money Coontroll application with Node.JS and Angular.js
 * This software is free for General Porpouses
 * @author: Max Andriani <max.andriani@gmail.com>
 */

var app = angular.module('myWallet');

// Routes
app.config(function($routeProvider) {
    $routeProvider

    // Default page: Transaction Grid
    .otherwise({
	templateUrl : 'app/public/public-view.html',
	controller : 'PublicController'
    })

    .when('/register', {
        templateUrl: 'app/public/register-form-view.html',
        controller: 'RegisterFormController'
    })

    // Single grid
    .when('/login', {
	templateUrl: 'app/public/login-form-view.html',
	controller: 'LoginFormController'
    });
});


text:
* [Crypto Broker Wallet Installation](stories/Crypto_Broker_Wallet_Installation.story)
* [Crypto Broker Identity Creation](stories/Crypto_Broker_Identity_Creation.story)
* [Crypto Broker Wallet Configuration](stories/Crypto_Broker_Wallet_Configuration.story)
* [Crypto Broker Wallet Stock Replenishment](stories/Crypto_Broker_Wallet_Stock_Replenishment.story)
* [Crypto Broker Publish](stories/Crypto_Broker_Publish.story)
* [Crypto Customer Sale Negotiation](stories/Crypto_Customer_Sale_Negotiation.story)
* [Crypto Customer Sale Execution](stories/Crypto_Customer_Sale_Execution.story)

## Crypto Customer
* [Crypto Customer Wallet Installation](stories/Crypto_Customer_Wallet_Installation.story)
* [Crypto Customer Identity Creation](stories/Crypto_Customer_Identity_Creation.story)
* [Crypto Broker Discovery](stories/Crypto_Broker_Discovery.story)
* [Crypto Broker Buy Negotiation](stories/Crypto_Broker_Buy_Negotiation.story)
* [Crypto Broker Buy Execution](stories/Crypto_Broker_Buy_Execution.story)


text:
* {
  font-size: 4em;
  font-weight: bold; }

QMainWindow {
  background-repeat: no-repeat;
  border-image: url(:/media/background-plain.png);
  background-position: top center;
  background-color: white; }

#titleLabel, #streamNameLabel, #streamTitleLabel {
  font-weight: bold; }

QListView {
  background-color: transparent; }

#StreamView {
  background-color: #E6E6E6; }
  #StreamView ::item {
    margin: 4px;
    border: 2px solid #355797;
    background-color: #E6E6E6;
    min-height: 50px;
    min-width: 250px; }

#scrollAreaWidgetContents #imageLabel {
  margin: -1px; }

QPushButton {
  min-width: 3em;
  min-height: 2em;
  border-radius: 10px;
  color: #355797;
  background-color: #FFFFFF;
  margin-bottom: 1em collapse; }
  QPushButton:hover {
    background-color: #7DB3DE; }
  QPushButton:flat {
    border: none;
    /* no border for a flat push button */
    background-color: #7DB3DE; }
  QPushButton:default {
    border-color: navy;
    /* make the default button prominent */ }

QPushButton:pressed {
  background-color: #4479BA;
  border-color: #042029;
  color: #042029; }

QComboBox {
  selection-background-color: #7DB3DE;
  border: 1px solid #355797;
  border-radius: 2px;
  padding: 10px;
  color: #355797; }
  QComboBox:disabled {
    color: #CDCDCD; }

QComboBox QAbstractItemView {
  background-color: #FFFFFF;
  border-radius: 2px;
  border: 1px solid #444; }

QComboBox, QPushButton {
  border: 2px solid #355797;
  padding-left: 10px;
  padding-right: 10px;
  padding-top: 5px;
  padding-bottom: 5px;
  font-weight: bold;
  max-height: 30px; }

QScrollBar:vertical {
  width: 7px;
  margin: 16px 0 16px 0;
  border: 2px solid #355797; }
  QScrollBar:vertical:groove {
    width: 10px; }

QScrollBar::handle:vertical {
  background: white;
  min-height: 10px;
  border: 2px solid #355797; }

QScrollBar::add-line:vertical {
  border: 2px solid #355797;
  border-radius: 2px;
  height: 14px;
  subcontrol-position: bottom;
  subcontrol-origin: margin; }

QScrollBar::sub-line:vertical {
  border: 2px solid #355797;
  border-radius: 2px;
  height: 14px;
  subcontrol-position: top;
  subcontrol-origin: margin; }

QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {
  border: 2px solid #355797;
  width: 1px;
  height: 1px;
  background: white; }

QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
  background: transparent; }

QScrollArea {
  border: 2px solid #355797;
  border-radius: 4px;
  background: transparent; }

QScrollArea:scrollAreaWidgetContents {
  background: transparent; }

QLabel#label_title, QLabel#streamName, #StreamView > #label {
  font-size: 30px; }

QLabel#label_image {
  border: 2px solid #355797;
  padding: 0px;
  margin: 0px; }

#SingleStreamView {
  background-color: transparent; }
  #SingleStreamView ::item {
    border: 2px solid #355797;
    background-color: #EDEDED;
    border-radius: .2em; }

#HomeView QLabel#versionLabel {
  font-size: 12px; }

/*# sourceMappingURL=ios.css.map */


text:
var async = require('async');
var fs = require('fs');
var https = require('https');
var prompt = require('prompt');
var url = require('url');

var verbose = false;
var user;
var pass;

main();

function get_path(path, callback) {

    var options = {
        hostname: 'api.github.com',
        port: 443,
        path: path,
        method: 'GET'
    }

    if (user && pass) {
        options.auth = user + ':' + pass;
    }

    var req = https.request(options, function (res) {
        var data = '';

        if (verbose) {
            console.log('statusCode: ', res.statusCode);
            console.log('headers: ', res.headers);
        }
        res.on('data', function (d) {
            // process.stdout.write(d);
            data += d;
        });
        res.on('end', function (d) {
            var json;
            try {
                json = JSON.parse(data, 'utf8');
                if (verbose) {
                    console.log('json = ' + JSON.stringify(json, undefined, 4));
                }
                if (res.statusCode !== 200) {
                    console.error('headers: ', res.headers);
                    return callback(new Error(res.statusCode + ' ' + JSON.stringify(json, undefined, 4)));
                }
                return callback(null, json);
            } catch (ex) {
                console.error(ex);
                return callback(ex);
            }
        });
    });
    req.end();

    req.on('error', function (error) {
        console.error(error);
        return callback(error);
    });
}

function get_repos(type, name, callback) {
    console.log(type + ' ' + name);
    get_path('/' + type + '/' + name + '/repos', function (error, json) {
        if (error) {
            return callback(error);
        }
        return callback(null, json);
    });
}

function list_repos() {
    var repos = [
        {
            type: 'users',
            name: 'jtraver'
        },
        {
            type: 'orgs',
            name: 'aerospike'
        },
        {
            type: 'orgs',
            name: 'citrusleaf'
        }
    ];
    var lines = '';

    async.forEachSeries(repos, function (repo, cb1) {
        get_repos(repo.type, repo.name, function (error, json) {
            if (error) {
                console.error(error);
                return cb1(error);
            }
            async.forEachSeries(json, function (repoJson, cb2) {
                var urlInfo = url.parse(repoJson.url);
                var line;
                get_path(urlInfo.path, function (error, fullRepo) {
                    if (error) {
                        return cb2(error);
                    }
                    if (fullRepo.parent) {
                        line = repo.name + ' ' + repoJson.ssh_url + ' ' + fullRepo.parent.ssh_url;
                    } else {
                        line = repo.name + ' ' + repoJson.ssh_url;
                    }
                    console.log(line);
                    lines += line + '\n';
                    return cb2(null);
                });
            }, function (error) {
                if (error) {
                    console.error(error);
                    return cb1(error);
                }
                return cb1(null);
            });
        });
    }, function (error) {
        if (error) {
            console.error(error);
            return;
        }
        fs.writeFileSync('repos.data', lines);
    });
}

function main() {
    var schema = {
        properties: {
            name: {
                required: true,
                message: "jtraver 12"
            },
            password: {
                hidden: true,
                required: true
            }
        }
    };

    prompt.get(schema, function (err, result) {
        if (err) {
            console.error(err);
            return;
        }
        user = result.name;
        pass = result.password;
        list_repos();
    });
}


text:
<?php
require APPPATH . '/language/english/master.php';
$lang['list'] = 'The permission table of the groups';
$lang['role'] = 'Role';
$lang['choosegroup'] = 'Choose Group';
$lang['fullpermission'] = 'Full Permission';
$lang['custom'] = 'Custom';
?>


text:
'use strict';

// Load the module dependencies
var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var logModel = new Schema({
    appId: {type: String, trim: true},
    channel: {type: String, trim: true},
    message: {type: String, trim: true},
    environment: {type: String, trim: true},
    severity: {type: Number},
    host: {type: String, trim: true},
    protocol: {type: String, trim: true},
    extras: {type: mongoose.Schema.Types.Mixed},
    processId: {type: Number},
    messageId: {type: Number},
    created: {type: Date, default: Date.now},
    update: {type: Date, default: Date.now},
    counter: {type: Number, default: 0, trim: true},
    fixed: {type: Boolean, default: false, trim: true},
    transport: {type: String, trim: true}
});

module.exports = mongoose.model('LogModel', logModel);


text:
require 'rubygems/command_manager'

if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.3.6')
  Gem::CommandManager.instance.register_command :keys
end


text:
copyright:
 years: 2015, 2016

---

{:new_window: target="_blank"}
{:shortdesc: .shortdesc}
{:screen:.screen}
{:codeblock:.codeblock}

# 使用 userId 登錄裝置
{: #register_device_with_userId}
前次更新:2016 年 12 月 7 日
{: .last-updated}

若要登錄 userId 型通知,請完成下列步驟:

## Android
{: android-register}

使用 {{site.data.keyword.mobilepushshort}} Service 的 `AppGUID` 及 `clientSecret` 金鑰,來起始設定 MFPPush 類別。
```
// Initialize the MFPPush
push = MFPPush.getInstance();
push.initialize(getApplicationContext(),"AppGUID", "clientSecret");
```
	{: codeblock}

- **AppGUID**:這是 {{site.data.keyword.mobilepushshort}} Service 的 AppGUID 金鑰。
- **clientSecret**:這是 {{site.data.keyword.mobilepushshort}} Service 的 clientSecret 金鑰。

  使用 **registerDeviceWithUserId** API 登錄裝置,以取得 {{site.data.keyword.mobilepushshort}}。
```
// Register the device to {{site.data.keyword.mobilepushshort}}.
push.registerDeviceWithUserId("userId",new MFPPushResponseListener<String>() {
    @Override
	    public void onSuccess(String deviceId) {
	           Log.d("Device is registered with Push Service.");
  }
  @Override
  public void onFailure(MFPPushException ex) {
    Log.d("Error registering with Push Service...\n"
        + "Push notifications will not be received.");
  }
});
```
	{: codeblock}

- **userId**:傳遞唯一 userId 值,以登錄 {{site.data.keyword.mobilepushshort}}。

**附註:**若要啟用 userId 設為目標的 {{site.data.keyword.mobilepushshort}},請確定您使用 userId 登錄裝置,同時也傳遞佈建 {{site.data.keyword.mobilepushshort}} Service 時所配置的 'clientSecret'。若沒有有效的 clientSecret,裝置登錄會失敗。

## Cordova
{: cordova}

使用下列 API 來登錄使用者 ID 型 {{site.data.keyword.mobilepushshort}}。

```
// Register device for push notification with UserId
var options = {"userId": "Your User Id value"};
BMSPush.registerDevice(options,success, failure);
```
	{: codeblock}

- **userId**:傳遞唯一 userId 值,以登錄 {{site.data.keyword.mobilepushshort}}。

## Objective-C
{: objc-register}

使用下列 API 來登錄以使用者 ID 為基礎的 {{site.data.keyword.mobilepushshort}}。
```
// Initialize the MFPPush
IMFPushClient* push = [IMFPushClient sharedInstance];
[push initializeWithAppGUID:@"appGUID" clientSecret:@"clientSecret"];
```
	{: codeblock}

- **AppGUID**:這是 {{site.data.keyword.mobilepushshort}} Service 的 AppGUID 金鑰。
- **clientSecret**:這是 {{site.data.keyword.mobilepushshort}} Service 的 clientSecret 金鑰。

使用 **registerWithUserId** API 登錄裝置,以取得 {{site.data.keyword.mobilepushshort}}。
```
// Register the device to push notifications service.
[push registerWithDeviceToken:deviceToken WithUserId:@"userId" completionHandler:^(IMFResponse *response, NSError *error) {
    NSString *message=@"";
	if (error){
        message = [NSString stringWithFormat:@"Error registering for push notifications: %@", error.description];
        NSLog(@"%@",message);
    } else {
        message=@"Successfully registered for push notifications";
        NSLog(@"%@",message);
    }
}];
```
	{: codeblock}

- **userId**:傳遞唯一 userId 值,以登錄 {{site.data.keyword.mobilepushshort}}。

## Swift
{: swift-register}

```
// Initialize the BMSPushClient
let push =  BMSPushClient.sharedInstance
push.initializeWithAppGUID("appGUID", clientSecret:"clientSecret")
```
	{: codeblock}

- **AppGUID**:這是 {{site.data.keyword.mobilepushshort}} Service 的 AppGUID 金鑰。
- **clientSecret**:這是 {{site.data.keyword.mobilepushshort}} Service 的 clientSecret 金鑰。

使用 **registerWithUserId** API 登錄裝置,以取得 {{site.data.keyword.mobilepushshort}}。

```
// Register the device to Push Notifications service.
push.registerWithDeviceToken("deviceToken", WithUserId: "userId")  { (response, statusCode, error) -> Void in
if error.isEmpty {

    print( "Response during device registration : \(response)")
        print( "status code during device registration : \(statusCode)")
    } else {
        print( "Error during device registration \(error) ")
    }
    }
```
	{: codeblock}

- **userId**:傳遞唯一 userId 值,以登錄 {{site.data.keyword.mobilepushshort}}。

## Google Chrome、Safari 及 Mozilla Firefox
{: web-register}

使用下列 API 來登錄 userId 型通知。使用 `app GUID`、`app Region` 及 `Client Secret` 來起始設定 SDK。

```
var bmsPush = new BMSPush();
var params = {
    "appGUID":"push app GUID",
    "appRegion":"App Region",
    "clientSecret":"Push Client Secret"
    }
  bmsPush.initialize(params, function(response){
          alert(response.response)
      })
```
	{: codeblock}

順利起始設定之後,請使用 userId 登錄 Web 應用程式。

```
    bmsPush.registerWithUserId("UserId", function(response) {
      alert(response.response)
  })
```
	{: codeblock}

## Google Chrome Apps and Extensions
{: web-register-new}

使用下列 API 來登錄 userId 型通知。使用 `app GUID`、`app Region` 及 `Client Secret` 來起始設定 SDK。

```
var bmsPush = new BMSPush();
var params = {
    "appGUID":"push app GUID",
    "appRegion":"App Region",
    "clientSecret":"Push Client Secret"
    }
  bmsPush.initialize(params, function(response){
          alert(response.response)
      })
```
	{: codeblock}

成功起始設定之後,您需要以使用者 ID 來登錄 Web 應用程式。

```
    bmsPush.registerWithUserId("UserId", function(response) {
      alert(response.response)
  })
```
	{: codeblock}

# 使用 userId 型通知
{: #using_userid}

userId 型通知是以特定使用者為目標的通知訊息。可向一個使用者登錄多個裝置。下列步驟說明如何傳送使用者 ID 型通知。

1. 從 **Push Notification** 儀表板中,選取**傳送通知**選項。
1. 在**傳送至**選項清單中,選取**使用者 ID**。
1. 在**使用者 ID** 欄位中,搜尋您要使用的使用者 ID,然後按一下 **+ 新增**。![通知畫面](images/user_notification.jpg)
1. 在**訊息**欄位中,輸入要在通知中傳送的文字。
1. 按一下**傳送**。


text:
static const int httpLogLevel = HTTP_LOG_LEVEL_VERBOSE;

@interface TAASTunnelResponse ()

@property (        nonatomic) BOOL                       connectedP;
@property (        nonatomic) BOOL                       errorP;

@property (strong, nonatomic) HTTPConnection            *parent;

@property (strong, nonatomic) GCDAsyncSocket            *upstream;
@property (nonatomic, weak) id<GCDAsyncSocketDelegate>   pDelegate;
@property (        nonatomic) dispatch_queue_t           pQueue;

@property (        nonatomic) dispatch_queue_t           delegateQueue;

@end

@implementation TAASTunnelResponse

- (id)initWithPath:(NSString *)path
        fromSocket:(GCDAsyncSocket *)socket
     forConnection:(HTTPConnection *)connection {
    if ((self = [super init]))  {
        uint16_t port = 80;
        NSString *host = path;
        NSRange range = [host rangeOfString:@":"];
        if (range.location != NSNotFound) {
            port = [[host substringFromIndex:(range.location + range.length)] intValue];
            host = [host substringToIndex:range.location];
        }
        HTTPLogInfo(@"%@[%p]: initWithPath: %@:%lu", THIS_FILE, self, host, (unsigned long)port);
// NB: the second part of fail-friendly
       range = [host rangeOfString:@".google.com" options:(NSBackwardsSearch | NSAnchoredSearch)];
       if ((range.location != NSNotFound) || ([host isEqualToString:@"google.com"])) {
           host = @"127.0.0.1";
           port = (port == 443) ? 8883 : 8884;
       }

        self.delegateQueue = dispatch_queue_create("TAASTunnelResponse socket delegate queue", 0);

        self.parent = connection;
        self.upstream = socket;
        self.pDelegate = self.upstream.delegate;
        self.upstream.delegate = self;
        self.pQueue = self.upstream.delegateQueue;
        self.upstream.delegateQueue = self.delegateQueue;
        self.downstream = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:self.delegateQueue];

        NSError *error = nil;
        [self.downstream connectToHost:host onPort:port error:&error];
        self.connectedP = self.errorP = NO;
    }

    return self;
}

- (void)abort {
    HTTPLogTrace();

    if (self.downstream != nil) {
        [self.downstream disconnect];
        self.downstream = nil;
    }
    if (self.parent == nil) return;

    self.upstream.delegate = self.pDelegate;
    self.upstream.delegateQueue = self.pQueue;
    self.upstream = nil;
    [self.parent responseDidAbort:self];
}

- (BOOL)isDone {
    HTTPLogTrace2(@"%@[%p]: isDone: %@", THIS_FILE, self, (self.downstream == nil) ? @"YES" : @"NO");

    return (self.downstream == nil);
}

- (void)connectionDidClose {
    HTTPLogTrace();

    if (self.upstream != nil) {
        self.upstream.delegate = self.pDelegate;
        self.upstream.delegateQueue = self.pQueue;
        self.upstream = nil;
    }
    self.parent = nil;
}

#pragma mark - delayed response

- (BOOL)delayResponseHeaders {
    HTTPLogTrace2(@"%@[%p]: delayResponseHeaders: %@", THIS_FILE, self, self.errorP ? @"NO" : @"YES");

    return (!self.errorP);
}

- (NSInteger)status {
    HTTPLogTrace2(@"%@[%p]: status:%d", THIS_FILE, self, 504);

    return 504;
}

- (NSDictionary *)httpHeaders {
    HTTPLogTrace();

    return nil;
}

-(NSData *)readDataOfLength:(NSUInteger)length {
    HTTPLogTrace2(@"%@[%p]: readDataOfLength: %lu", THIS_FILE, self, (unsigned long)length);

    return nil;
}

#pragma mark - dynamic data

- (BOOL)isChunked {
    HTTPLogTrace();

    return YES;
}

- (UInt64)contentLength {
    HTTPLogTrace();

    return 0;
}

- (UInt64)offset {
    HTTPLogTrace();

    return 0;
}

- (void)setOffset:(UInt64)offset {
    HTTPLogTrace2(@"%@[%p]: setOffset: %lu", THIS_FILE, self, (unsigned long)offset);
}

#pragma mark - GCDAsyncSocket delegate methods

#define TUNNEL_CONNECTED    2000
#define TUNNEL_CONFIRMED    2001
#define TUNNEL_READ         2002
#define TUNNEL_WRITE        2003

-   (void)socket:(GCDAsyncSocket *)sock
didConnectToHost:(NSString *)host
            port:(uint16_t)port {
    HTTPLogTrace2(@"%@[%p]: didConnectToHost: %@:%lu", THIS_FILE, self, host, (unsigned long)port);

    [self socket:self.downstream
     didReadData:[[NSString stringWithFormat:@"HTTP/1.0 200 OK\r\n\r\n"]
                   dataUsingEncoding:NSUTF8StringEncoding]
         withTag:TUNNEL_CONNECTED];
    self.connectedP = YES;
}

- (void)socket:(GCDAsyncSocket *)sock
   didReadData:(NSData *)data
       withTag:(long)tag {
    HTTPLogTrace2(@"%@[%p]: didReadData: %@ length=%lu tag=%lu", THIS_FILE, self,
                  (sock == self.downstream) ? @"downstream" : @"upstream", (unsigned long)data.length,
                  tag);

    GCDAsyncSocket *peer = (sock == self.downstream) ? self.upstream : self.downstream;

    [peer writeData:data withTimeout:-1 tag:tag];
    [peer readDataWithTimeout:-1 tag:TUNNEL_READ];
    [sock readDataWithTimeout:-1 tag: TUNNEL_READ];
}

-      (void)socket:(GCDAsyncSocket *)sock
didWriteDataWithTag:(long)tag {
    HTTPLogTrace2(@"%@[%p]: didWriteDataWithTag: %@ tag=%lu", THIS_FILE, self,
                  (sock != self.downstream) ? @"upstream" : @"downstream", tag);
}

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock
                  withError:(NSError *)error {
    if ((error != nil)
            && ((![error.domain isEqualToString:@"GCDAsyncSocketErrorDomain"]) || (error.code != 7))) {
        HTTPLogError(@"%@[%p] socketDidDisconnect: %@", THIS_FILE, self, error);
    }

    if (self.connectedP) {
        [self abort];
        return;
    }

    self.errorP = YES;
    [self.parent responseHasAvailableData:self];
}

@end


text:
SRV_PRIV=$(head -n 1 servers_public_private | cut -d' ' -f2)
SRV_PUB=$(head -n 1 servers_public)
echo Configuring sync with server $SRV_PUB / $SRV_PRIV

cat ntp.conf.template | sed -e "s/server\ 127.127.1.1/server\ $SRV_PRIV prefer/" | sed -e "s/fudge\ \ 127.127.1.1 stratum 10//" > ntp.conf

echo Setting up NTP clients
for pubip in `cat servers_public`
do
    echo Server $pubip
    scp ntp.conf ubuntu@${pubip}:/tmp
    ssh ubuntu@${pubip} "sudo cp /tmp/ntp.conf /etc/ntp.conf"
done

echo Setting up NTP server $SRV_PUB
cp ntp.conf.template ntp.conf
scp ntp.conf ubuntu@${SRV_PUB}:/tmp
ssh ubuntu@${SRV_PUB} "sudo cp /tmp/ntp.conf /etc/ntp.conf"

echo Restarting NTP
for pubip in `cat servers_public`
do
    echo Server $pubip
    ssh ubuntu@${pubip} "sudo service ntp restart"
done

./ntp_sweep.sh


text:
import { ChatComponent } from './meeting/chat/chat.component';
import { MatchesComponent } from './meeting/matching/matches.component';
import { FormsModule } from '@angular/forms';
import { InscriereTombolaComponent } from './tombole/tombola.inscriere.component';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { MaterializeModule } from 'angular2-materialize';

import { AngularFireModule } from 'angularfire2';
import { AngularFireDatabaseModule } from 'angularfire2/database';
import { AngularFireAuthModule } from 'angularfire2/auth';

import { environment } from '../environments/environment';
import { AppComponent } from './app.component';
import { UserComponent } from './user/user.component';
import { LoginComponent } from './login/login.component';
import { LandingComponent } from './landing/landing.component';
import { TomboleComponent } from './tombole/tombole.component';
import { VotesComponent } from './vote/vote.component';
import { TombolaComponent } from './tombole/tombola.component';
import { AuthGuard } from './authGuard.service';
import { AccountService } from './services/account.service';
import { QuestionsComponent } from './meeting/questions.component';
import { BereComponent } from './bere/bere.component';

const appRoutes: Routes = [
  {
    path: 'home',
    component: LandingComponent,
  },
  {
    path: 'login',
    component: LoginComponent,
  },
  {
    path: 'meeting',
    component: MatchesComponent,
    canActivate: [AuthGuard],
  },
  {
    path: 'questions',
    component: QuestionsComponent,
    canActivate: [AuthGuard],
  },
  {
    path: 'vote',
    component: VotesComponent,
    canActivate: [AuthGuard],
  },
  {
    path: 'tombole',
    component: TomboleComponent,
    canActivate: [AuthGuard],
  },
  {
    path: 'tombola/:id',
    component: InscriereTombolaComponent,
    canActivate: [AuthGuard],
  },
  {
    path: 'user',
    component: UserComponent,
    canActivate: [AuthGuard],
  },
  {
    path: 'chat/:id',
    component: ChatComponent,
    canActivate: [AuthGuard],
  },
  {
    path: '',
    redirectTo: '/login',
    pathMatch: 'full'
  },
  {
    path: 'bere',
    component: BereComponent,
    canActivate: [AuthGuard],
  }
  // { path: '**', component: PageNotFoundComponent }
];

@NgModule({
  declarations: [
    UserComponent,
    AppComponent,
    LoginComponent,
    LandingComponent,
    TomboleComponent,
    VotesComponent,
    TombolaComponent,
    InscriereTombolaComponent,
    QuestionsComponent,
    MatchesComponent,
    ChatComponent,
    BereComponent,
  ],
  imports: [
    BrowserModule,
    MaterializeModule,
    FormsModule,
    RouterModule.forRoot(
      appRoutes,
      { enableTracing: false } // <-- debugging purposes only
    ),
    AngularFireModule.initializeApp(environment.firebase), // imports firebase/app needed for everything
    AngularFireDatabaseModule, // imports firebase/database, only needed for database features
    AngularFireAuthModule, // imports firebase/auth, only needed for auth features
  ],
  providers: [
    AuthGuard,
    AccountService,
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }