We're currently working on bringing meta functionality to sites and networks. While this is still in the early stages of discussion, we're sure that we would at least like to enable plugins to introduce this functionality (DB table and API), even if we come to the conclusion that site and network meta are not eligible for core itself (see #37923 and #25344 for background discussion on site and network meta).
They should be loaded together with the other "early" WordPress files. This does not only make sense for the above specific use-case, but also because the meta API is a generally reusable basic database interaction API and allows to work with arbitrary "name-value" pairs, just like options. The Options API is also available early, and the Meta API should follow.
Whoops, typo in the summary.
This is a requirement for the site meta API we're planning (and also for network meta if we do it).
As noted during the work on #37923, wp-includes/formatting.php needs to be loaded early as well, since the metadata API requires parts of it.
I'm not really opposed to getting this in earlier than later. It would be nice to know that not having these available earlier is currently blocking someone's external work.
From a core perspective, we'll be moving formatting.php and meta.php up in the boot process in #37923 anyway. The others can be moved as part of #40229 if they aren't already.
Bootstrap: Load formatting.php and meta.php earlier in wp-settings.php.
This change is necessary to enable multisite-specific metadata functionality during the multisite bootstrap process.
For #40229 we'll still need to move the class-wp-meta-query.php to be loaded earlier, as mentioned before.
Should  be reverted until all edge cases are fixed?
Also, formatting.php shouldn't be needed for accessing the db. I'd rather move sanitize_key() or introduce a similar function than load a file that is clearly intended for formatting the PHP output while accessing the db.
Noting that the above is already fixed in . What other edge cases are there? And how would you find them if things get reverted?
@barry Seems that this bug had indeed already been reported via #43609 and fixed in  as @ocean90 stated above. Can you verify that solves the problem on wp.com?
Reverting  is not really an option since other functionality is built on it that requires some of the functions to be loaded early. I'd like to emphasize what was said before, that reverting furthermore wouldn't allow us to find these bugs. If there's anything else, please report on this ticket or as an individual ticket referencing this one, and we'll get it fixed.


text:
    <button type="action" name="act_pericias">Pericias y Combate</button>
    <button type="action" name="act_tesoro">Tesoro y Talentos</button>
    <button type="action" name="act_diario">Grimorio</button>
    <button type="action" name="act_devocion">Devoción</button>
    <button type="action" name="act_monstruos">Monstruos</button>

<input type="hidden" class="sheet-tabstoggle" name="attr_sheetTab" value="pericias" />

            NOMBRE

    <input type="text" name="attr_character_name" />

    Clase

    <input type="text" class="w100" name=attr_ClasePJ>

    <button type='roll' value='&{template:default} {{name=@{character_name} tira sus pg después del Entretiempo}} {{Resultado=[[@{DG}]]}}' name='roll_tirada_DG'></button>
    Dados de Golp

<input type="text" name="attr_DG" class="w70">

    Gloria

    <input type="text" name="attr_ptsGloria" />

    Fama

    <input type="text" class="w100" name=attr_Fama>

    <button type='roll' value='&{template:default} {{name=@{character_name} se esfuerza en el camino}} {{Resultado=[[1d6+@{modSab}]]}}' name='roll_tarea_camino'></button>
    Tareas del camino y PM

    <input type="number" name="attr_PM" class="w70">

Características y Pericias

        Punt.

        Mod.

        Pericias

        <button type='roll' value='&{template:default} {{name=@{character_name} tira Fuerza}} {{Resultado=[[1d20]]}} {{Fuerza=[[@{Fue}]]}}' name='tirada_Fue'></button>Fuerza

        <input type="number" name="attr_Fue" />

        <input type="number" name="attr_modFue" />

        <input type="text" style=style=width:450px;height:28px name="attr_PerFue">

        <button type='roll' value='&{template:default} {{name=@{character_name} tira Destreza}} {{Resultado=[[1d20]]}} {{Destreza=[[@{Des}]]}}' name='tirada_Des'></button>Destreza

        <input type="number" name="attr_Des" />

        <input type="number" name="attr_modDes" />

        <input type="text" style=style=width:450px;height:28px name="attr_PerDes">

        <button type='roll' value='&{template:default} {{name=@{character_name} tira Constitución}} {{Resultado=[[1d20]]}} {{Constitución=[[@{Con}]]}}' name='tirada_Con'></button>Constitución

        <input type="number" name="attr_Con" />

        <input type="number" name="attr_modCon" />

        <input type="text" style=style=width:450px;height:28px name="attr_PerCon">

        <button type='roll' value='&{template:default} {{name=@{character_name} tira Inteligencia}} {{Resultado=[[1d20]]}} {{Inteligencia=[[@{Int}]]}}' name='tirada_Int'></button>Inteligencia

        <input type="number" name="attr_Int" />

        <input type="number" name="attr_modInt" />

        <input type="text" style=style=width:450px;height:28px name="attr_PerInt">

        <button type='roll' value='&{template:default} {{name=@{character_name} tira Sabiduría}} {{Resultado=[[1d20]]}} {{Sabiduría=[[@{Sab}]]}}' name='tirada_Sab'></button>Sabiduría

        <input type="number" name="attr_Sab" />

        <input type="number" name="attr_modSab" />

        <input type="text" style=style=width:450px;height:28px name="attr_PerSab">

        <button type='roll' value='&{template:default} {{name=@{character_name} tira Carisma}} {{Resultado=[[1d20]]}} {{Carisma=[[@{Car}]]}}'></button>Carisma

        <input type="number" name="attr_Car" />

        <input type="number" name="attr_modCar" />

        <input type="text" style=style=width:450px;height:28px name="attr_PerCar">

    Pts de Golpe
    <input type="text" name=attr_pgTotales class="w32">
    <input type="text" name=attr_pgActuales class="w32">

    Clase de Armadura
    <input type="text" name=attr_CA class="w32" value="10">

    DA base
    <select name="attr_DA" class="dtype sword">
    		<option value="d1">1</option>
    		<option value="d4">d4</option>
    		<option value="d6">d6</option>
    		<option value="d8">d8</option>
    		<option value="d10">d10</option>
    		<option value="d12">d12</option>
    		<option value="d20">d20</option>
            </select>

     Velocidad
    <input type="text" name=attr_Vel class="w32" value=10>

Armas

        DA

        Daño

        Propiedades

        Dureza

        Peso

        <button type='roll' value='&{template:default} {{name=¡@{character_name} se lanza al ataque con su @{arma1}!}} {{Resultado=[[@{DA1}]]}} {{Daño=[[@{daño1}]]}}' name="roll_arma1"></button>
        <input type="text" class="w150" value='Arma' name="attr_arma1">

        <select name="attr_DA1" class="dtype" value=@{DA}>
                <option value="d1">1</option>
                <option value="d4">d4</option>
                <option value="d6">d6</option>
                <option value="d8">d8</option>
                <option value="d10">d10</option>
                <option value="d12">d12</option>
                <option value="d20">d20</option>
                </select>

<input type="text" name="attr_daño1" class="w85" value='1d6+1'>

<input type="text" class="w240" name="attr_propiedadesA1">

<input type="number" name="attr_durezaA1">

<input type="number" name="attr_pesoA1" value="0">

<button type='roll' value='&{template:default} {{name=¡@{character_name} se lanza al ataque con su @{arma2}!}} {{Resultado=[[@{DA2}]]}} {{Daño=[[@{daño2}]]}}' name="roll_arma2"></button>
        <input type="text" class="w150" value='Arma' name="attr_arma2">

        <select name="attr_DA2" class="dtype" value=@{DA}>
                <option value="d1">1</option>
                <option value="d4">d4</option>
                <option value="d6">d6</option>
                <option value="d8">d8</option>
                <option value="d10">d10</option>
                <option value="d12">d12</option>
                <option value="d20">d20</option>
                </select>

<input type="text" name="attr_daño2" class="w85" value='1d6+1'>

<input type="text" class="w240" name="attr_propiedadesA2">

<input type="number" name="attr_durezaA2">

<input type="number" name="attr_pesoA2" value="0">

<button type='roll' value='&{template:default} {{name=¡@{character_name} se lanza al ataque con su @{arma3}!}} {{Resultado=[[@{DA3}]]}} {{Daño=[[@{daño3}]]}}' name="roll_arma3"></button>
        <input type="text" class="w150" value='Arma' name="attr_arma3">

<select name="attr_DA3" class="dtype" value=@{DA}>
                <option value="d1">1</option>
                <option value="d4">d4</option>
                <option value="d6">d6</option>
                <option value="d8">d8</option>
                <option value="d10">d10</option>
                <option value="d12">d12</option>
                <option value="d20">d20</option>
                </select>

<input type="text" name="attr_daño3" class="w85" value='1d6+1'>

<input type="text" class="w240" name="attr_propiedadesA3">

<input type="number" name="attr_durezaA3">

<input type="number" name="attr_pesoA3" value="0">

Protecciones

        CA

        Dureza

        Actual

        Tipo

        Propiedades

        Peso

<input type="text" class="w175" value='Armadura' name="attr_Prtcc1">

<input type="number" name="attr_CAP1" class="w60">

<input type="number" name="attr_durezaP1" class="w60">

<input type="number" name="attr_dureza-actualP1" class="w60">

<input type="text" class="w60" name="attr_tipoP1">

<input type="text" class="w225" name="attr_propiedadesP1">

<input type="number" name=attr_pesoP1 value="0">

<input type="text" class="w175" value='Armadura' name="attr_Prtcc2">

<input type="number" name="attr_CAP2">

<input type="number" name="attr_durezaP2">

<input type="number" name="attr_dureza-actualP2" class="w60">

<input type="text" class="w60" name="attr_tipoP2">

<input type="text" class="w225" name="attr_propiedadesP2">

<input type="number" name=attr_pesoP2 value="0">

<input type="text" class="w175" value='Armadura' name="attr_Prtcc3">

<input type="number" name="attr_CAP3">

<input type="number" name="attr_durezaP3">

<input type="number" name="attr_dureza-actualP3" class="w60">

<input type="text" class="w60" name="attr_tipoP3">

<input type="text" class="w225" name="attr_propiedadesP3">

<input type="number" name=attr_pesoP3 value="0">

<input type="text" class="w175" value='Armadura' name="attr_Prtcc4">

<input type="number" name="attr_CAP4">

<input type="number" name="attr_durezaP4">

<input type="number" name="attr_dureza-actualP4" class="w60">

<input type="text" class="w60" name="attr_tipoP4">

<input type="text" class="w225" name="attr_propiedadesP4">

<input type="number" name=attr_pesoP4 value="0">

<input type="text" class="w175" value='Armadura' name="attr_Prtcc5">

<input type="number" name="attr_CAP5">

<input type="number" name="attr_durezaP5">

<input type="number" name="attr_dureza-actualP5" class="w60">

<input type="text" class="w60" name="attr_tipoP5">

<input type="text" class="w225" name="attr_propiedadesP5">

<input type="number" name=attr_pesoP5 value="0">

Peso Total <input type="number" name="attr_pesoTotal" value="(@{pesoA1}+@{pesoA2})+(@{pesoA3}+@{pesoP1})+(@{pesoP2}+@{pesoP3})+(@{pesoP4}+@{pesoP5})" disabled="true" />

La Bolsa

                <input type="text" class="w150" name="attr_bolsa1">
                <input type="text" class="w150" name="attr_bolsa2">

Tesoro

                    <input type="text" class="w150" name="attr_tesoro1">
                    <input type="text" class="w150" name="attr_tesoro2">

                    <input type="text" class="w150" name="attr_tesoro3">
                    <input type="text" class="w150" name="attr_tesoro4">

                    <input type="text" class="w150" name="attr_tesoro5">
                    <input type="text" class="w150" name="attr_tesoro6">

                    <input type="text" class="w150" name="attr_tesoro7">
                    <input type="text" class="w150" name="attr_tesoro8">

                    <input type="text" class="w150" name="attr_tesoro9">
                    <input type="text" class="w150" name="attr_tesoro10">

Alijo

            <textarea style="width:300px;height:150px;" name="attr_alijo">Anota aquí lo que dejes a buen recaudo en tu guarida.</textarea>

Hitos del Personaje

            <fieldset class="repeating_character-hitos" style="display: none;">

                    <input type="text" class="w150" name="attr_hitos1">
                    <input type="text" class="w150" name="attr_hitos2">

            </fieldset>

Talentos de Clase

            <fieldset class="repeating_character-talentos-clase" class="repeating_talentos">
                <textarea name="attr_talento-clase">Descripción</textarea>
            </fieldset>

Talentos de Prestigio y Lealtad

            <fieldset class="repeating_character-talentos-prestigio" style="display: none;">

                    <textarea style="width:350px;height:52px;margin-bottom:5px" name="attr_desc-prestigio2">Descripción</textarea>

            </fieldset>

Armas que no llevas encima

            DA

            Daño

            Propiedades

            Dureza

            Peso

            <button type='roll' value='&{template:default} {{name=¡@{character_name} se lanza al ataque con su @{arma4}!}} {{Resultado=[[@{DA4}]]}} {{Daño=[[@{daño4}]]}}' name="roll_arma4"></button>
            <input type="text" class="w150" value='Arma' name="attr_arma4">

            <select name="attr_DA4" class="dtype" value=@{DA}>
                <option value="d1">1</option>
                <option value="d4">d4</option>
                <option value="d6">d6</option>
                <option value="d8">d8</option>
                <option value="d10">d10</option>
                <option value="d12">d12</option>
                <option value="d20">d20</option>
                </select>

<input type="text" name="attr_daño4" class="w85" value='1d6+1'>

<input type="text" class="w240" name="attr_propiedadesA4">

<input type="number" name="attr_durezaA4">

<input type="number" name="attr_pesoA4" value="0">

<button type='roll' value='&{template:default} {{name=¡@{character_name} se lanza al ataque con su @{arma5}!}} {{Resultado=[[@{DA5}]]}} {{Daño=[[@{daño5}]]}}' name="roll_arma5"></button>
            <input type="text" class="w150" value='Arma' name="attr_arma5">

            <select name="attr_DA5" class="dtype" value=@{DA}>
                <option value="d1">1</option>
                <option value="d4">d4</option>
                <option value="d6">d6</option>
                <option value="d8">d8</option>
                <option value="d10">d10</option>
                <option value="d12">d12</option>
                <option value="d20">d20</option>
                </select>

<input type="text" name="attr_daño5" class="w85" value='1d6+1'>

<input type="text" class="w240" name="attr_propiedadesA5">

<input type="number" name="attr_durezaA5">

<input type="number" name="attr_pesoA5" value="0">

<button type='roll' value='&{template:default} {{name=¡@{character_name} se lanza al ataque con su @{arma6}!}} {{Resultado=[[@{DA6}]]}} {{Daño=[[@{daño6}]]}}' name="roll_arma6"></button>
            <input type="text" class="w150" value='Arma' name="attr_arma6">

<select name="attr_DA6" class="dtype" value=@{DA}>
                <option value="d1">1</option>
                <option value="d4">d4</option>
                <option value="d6">d6</option>
                <option value="d8">d8</option>
                <option value="d10">d10</option>
                <option value="d12">d12</option>
                <option value="d20">d20</option>
                </select>

<input type="text" name="attr_daño6" class="w85" value='1d6+1'>

<input type="text" class="w240" name="attr_propiedadesA6">

<input type="number" name="attr_durezaA6">

<input type="number" name="attr_pesoA6" value="0">

Hechicería

Dado de Hechicería y Umbral de Poder

                    <button type='roll' value='&{template:default} {{name=@{character_name} intenta conjurar}} {{Resultado=[[@{canDH}]]}} {{UP=[[@{UP}]]}}' name='roll_tirada_conjuración'></button>
                    DH real
    <select name="attr_DH" class="dtype">
                        <option value="d1">1</option>
                        <option value="d4">d4</option>
                        <option value="d6">d6</option>
                        <option value="d8">d8</option>
                        <option value="d10">d10</option>
                        <option value="d12">d12</option>
                        <option value="d20">d20</option>
                    </select>
    DH canalizado
    <select name="attr_canDH" class="dtype">
                        <option value="d1">1</option>
                        <option value="d4">d4</option>
                        <option value="d6">d6</option>
                        <option value="d8">d8</option>
                        <option value="d10">d10</option>
                        <option value="d12">d12</option>
                        <option value="d20">d20</option>
                    </select>
    UP  :
    <input type="number" name="attr_UP" style="width:50px;height:28px">

Símbolos de Poder

        <input type="text" class="w110" name="attr_SP1">
        <input type="text" class="w110" name="attr_SP2">
        <input type="text" class="w110" name="attr_SP3">

Trucos

<textarea style="width:300px;height:100px;" name="attr_trucos">Escribe aquí los trucos de tu conjurador</textarea>

Notas adicionales

<textarea style="width:300px;height:300px;" name="attr_notas-hechicería">¿Qué otros poderes escondes?</textarea>

Conjuros Preparados

<textarea name="Text1" style="width:300px;height:150px;" name="attr_conjuros-preparados">Escribe aquí, nivel y todo, los conjuros que tengas listos para usar.</textarea>

Conjuros Conocidos

    <fieldset class="repeating_conjuros-conocidos" style="display: none;">

            <input type="text" class="w125" name="attr_conjuros-conocidos1">
            <input type="text" class="w125" name="attr_conjuros-conocidos2">
            <input type="text" class="w125" name="attr_conjuros-conocidos3">

    </fieldset>

Devoción

                <fieldset class="repeating_deidades" style="display: none;">

Deidad

                        <input type="text" class="w150 margin" name="attr_deidad1">
                        Reserva de Devoción
                        <input type="number" class="w60" name="attr_devocion1">

Dominios

                        <input type="text" name="attr_dominio1" class="margin">
                        <input type="text" name="attr_dominio2" class="margin">
                        <input type="text" name="attr_dominio3" class="margin">

Ritos

<textarea style="width:350px;height:150px;" name="attr_ritos1"></textarea>

                </fieldset>

                <fieldset class="repeating_deidades2" style="display: none;">

Uso de los Dominios

<textarea style="width:350px;height:250px;" name="attr_desc-dominios"></textarea>

                </fieldset>

Monstruos

Tipo <input type="text" class="w150" name="attr_tipo">

<button type='roll' value='/w gm Aparecen [[@{numberE}]] @{character_name}'></button>
         Número (encuentro)<input type="text" class="w60" name="attr_numberE">

<button type='roll' value='/w gm @{character_name} tiene [[@{DG}]] pg'></button>
        Dados de Golpe <input type="text" name="attr_DG" class="w60">

<button type='roll' value='&{template:default} {{name=@{character_name} se pone a prueba}} {{Resultado=[[1d20]]}}' name='tirada_salvación'></button>
        Salvaciones

<input type="text" class="w200" name="attr_salvaciones">

<button type='roll' value='/w gm @{character_name} tira Moral (@{moral}), [[2d6]]' name='tirada_moral'></button>
        Moral <input type="number" name="attr_moral">

<button type='roll' value='/w gm @{character_name} tira Reacción, [[@{reacción}+2d6]]' name='tirada_reacción'></button>
        Reacción  <input type="text" name="attr_reacción" style=style=width:60px;height:28px />

<button type='roll' value='/w gm En su guarida viven [[@{numberG}]] @{character_name}'></button>
        Número (guarida)<input type="text" class="w60" name="attr_numberG">

PG <input type="number" name="attr_pgTotales" />
         //
        <input type="number" name="attr_pgActuales" />

Velocidad <input type="number" name="attr_Vel">

Clase de Armadura <input type="number" name="attr_CA">

Gloria <input type="number" name="attr_gloria" class="w120">

        DA

        Daño

        Propiedades

        <button type='roll' value='&{template:default} {{name=¡@{character_name} se lanza al ataque con su @{arma1}!}} {{Resultado=[[@{DA1}]]}} {{Daño=[[@{daño7}]]}}' name="roll_arma1"></button>
        <input type="text" class="w150" value='Arma' name="attr_arma1">

        <select name="attr_DA1" class="dtype" value=@{DA}>
            <option value="d1">1</option>
            <option value="d4">d4</option>
            <option value="d6">d6</option>
            <option value="d8">d8</option>
            <option value="d10">d10</option>
            <option value="d12">d12</option>
            <option value="d20">d20</option>
            </select>

<input type="text" name="attr_daño7" class="w85" value='1d6+1'>

<input type="text" class="w240" name="attr_propiedadesA1">

<button type='roll' value='&{template:default} {{name=¡@{character_name} se lanza al ataque con su @{arma2}!}} {{Resultado=[[@{DA2}]]}} {{Daño=[[@{daño2}]]}}' name="roll_arma2"></button>
        <input type="text" class="w150" value='Arma' name="attr_arma2">

        <select name="attr_DA2" class="dtype" value=@{DA}>
            <option value="d1">1</option>
            <option value="d4">d4</option>
            <option value="d6">d6</option>
            <option value="d8">d8</option>
            <option value="d10">d10</option>
            <option value="d12">d12</option>
            <option value="d20">d20</option>
            </select>

<input type="text" name="attr_daño2" class="w85" value='1d6+1'>

<input type="text" class="w240" name="attr_propiedadesA2">

<button type='roll' value='&{template:default} {{name=¡@{character_name} se lanza al ataque con su @{arma3}!}} {{Resultado=[[@{DA3}]]}} {{Daño=[[@{daño3}]]}}' name="roll_arma3"></button>
        <input type="text" class="w150" value='Arma' name="attr_arma3">

<select name="attr_DA3" class="dtype" value=@{DA}>
            <option value="d1">1</option>
            <option value="d4">d4</option>
            <option value="d6">d6</option>
            <option value="d8">d8</option>
            <option value="d10">d10</option>
            <option value="d12">d12</option>
            <option value="d20">d20</option>
            </select>

<input type="text" name="attr_daño3" class="w85" value='1d6+1'>

<input type="text" class="w240" name="attr_propiedadesA3">

Notas adicionales

<textarea style="width:500px;height:150px;" name="attr_notas-adicionales"></textarea>

redpajama_set_name: RedPajamaGithub


Catch up on all the newest migraine headlines.
"You can hear the hopeful excitement in Grosberg's voice as he explains the potential impact of the study," writes MRF Ambassador Lisa Benson in this piece about Project Status Migrainosus, the groundbreaking study that received our first MRF Impact Award. Read more about the exciting new research by Dr. Brian Grosberg and Dr. Rami Burstein.
MRF Grantee Dr. Richard Kraig founded a startup based on the discoveries he made with his MRF grant. His new company Seurat Therapeutics will investigate a nasal spray to treat and prevent migraine headaches. This article explains what they'll do with the $250,000 investment they just received.
We are once again an official charity partner of the world's most popular marathon, and we have a guaranteed-entry spot waiting for you! Read the rules and view the application for Team MRF now.
This piece in Vice's Tonic discusses the links between migraine, birth control, and stroke risk. Most importantly, the author notes that not only are many hormonal birth control options safe for migraine sufferers, but they can even help prevent migraines in some women.
Migraine, tension headaches, and irritable bowel syndrome linked?
Researchers know that migraine sufferers are more likely to have IBS than non-sufferers. What they don't know is why. In this study, scientists identified two different genes that could be the key. Both IBS sufferers and migraine sufferers often have differences in these genes compared to non-sufferers. The researchers say that this discovery could lead to new, more targeted treatments for both conditions.
Sensei Christine is a black belt in karate, but she can't kick her migraines and cluster headaches. Her pain recently forced her to stop practicing and teaching karate lessons, but she wouldn't let it knock her out completely. Read how Christine and her students raised more than $1,700 for migraine research.
This is a comprehensive guide to treating the four different types of chronic daily headache. It includes a step-by-step treatment plan, specific talking points, and recommended medicines. Headache specialists and neurologists can use this guide to ensure they're treating patients in the best way possible, and you can use it to make sure your doctor has everything covered.
In this thoughtful essay in The New Yorker, Atul Gawande explains why headache specialists are our heroes. Get comfortable (it's a long read!) and prepare to read an important and moving piece dedicated to doctors who focus on overall, long-term health and well-being.
Get the latest migraine research news right to your inbox. Sign up for our mailing list now.


So which is it, a call center or a contact center? Aren't they the same thing?
Today you very often hear people refer to their center as a call center or a contact center and often interchange the two as if they are one and the same.
I would argue that there is a very big difference between the two and multi-channel is that difference.
Back in the day (I won't define when, because it makes me feel older than I already do) it was common to see call centers sprouting up throughout the United States and abroad. Some were inbound centers, and some outbound, but regardless they were "call centers" because they handled telephone calls and that's what they were focused on; making and taking telephone calls.
As the years went on we realized that customers desired other means of getting help from a company with which they do business and these centers began handling faxes too. Soon email became a channel and so on, launching us into the world of contact centers, where it was not just about telephone calls any longer.
Certainly in most centers today, telephone calls are often still the majority of the contacts handled but we are starting to see many more channels being added by companies as available options for a customer to reach a company.
I recently co-hosted a webinar and during the session we polled the audience of around 200 contact center specialists and found that about 75% of them had more than 2 channels and 43% actually had 3 or 4 different channels or options for customers to get help.
These channels likely consist of calls, faxes, emails, and chats. What I expect to see being added shortly are SMS (text messaging) and social media. Video is certainly possible but I don't see it going mainstream for many more years. This is likely a very niche channel that will apply to certain products or companies, but I can certainly see the day, with the abundance of smart phones that you can video conference with an agent, showing him or her the problem with the widget they wish to get help on. Or even taking a video of a widget and uploading it to a company website along with a trouble ticket that shows the problem they are having without going into a lot of detail over a chat or phone call.
The key to multi-media in your contact center is to use the right kind of contact for the right product or service and make many options available to your customer.
For example, you may choose to only service your high value customer with a live agent, and the best agent at that. But your tech support group may utilize chat as the customer is more comfortable speaking about a technical problem over chat. Finding the right balance between agent served contacts and self-service is critical too, but that is a topic for next time.
For now, the goal is to get a benchmark of your customer base. Understand who they are and how they want to communicate and create channels that suit your customers instead of focusing only on how to solve your own internal contact center pain. Fix problems from the outside in rather than the other way around, and be willing to test your channels to understand customer experience.
Call into your center with a billing question. Chat with an agent and see if they are courteous (and good spellers) or browse your knowledge base with a specific problem and try to solve it with the information available. If it does not go so well, you have some quick wins you can go after to improve customer experience.
Remember, it needs to be about the customer and how they wish to be helped.


We still remember the day when we reached 100 subscribers on YouTube for our ASMR YouTube channel. That was pretty exciting, so to reach 20,000 is pretty awesome. To celebrate, we created a video with 20 different sounds including crinkles, tapping, scratching and scraping sounds.
We want to thank each of our subscribers and we will be bringing more to you soon.


text:
John Boyega Gives an Overview of Star Wars Battlefront II
By Jack Gardner
With Star Wars Battlefront II a little over a month and a half away, EA has begun kicking the hype machine into high gear. That that end, the colossal game publisher has thrown its weight around to get the lovable John Boyega, who portrays Finn in Star Wars Episode VII-???, to talk about Star Wars Battlefront II's various features and mechanics.
Not going to lie - the first iteration of the current Star Wars Battlefront cycle released with impressive visuals, but lacking in content. Star Wars Battlefront II seems to be angling to address that problem by providing a variety of different modes, a single-player campaign, local co-op, fourteen different maps, and an overhauled system to allow anyone to earn different in-game drops like spawning as a hero or elite trooper.
Star Wars Battlefront II launches on November 17 for PlayStation 4, Xbox One, and PC.
Extra Life Best Practices
Streaming 101 for Extra Life
By herobyclicking
Seamlessly Integrate Extra Life and Facebook Fundraising
By Talitha
Fundraise on the go with the Extra Life Mobile App
Extra Life Instruction Manual
Gaming Marathons - The Healthy Way
By Kash

redpajama_set_name: RedPajamaCommonCrawl


This preview shows page 7 - 17 out of 26 pages.
followed to reach that node. The root is the most accessible node. 5 8 15 9 29 11 What is the depth of the root? The root always has a depth of 0. The depth of a tree is the depth of the deepest node.
Binary search tree A binary search tree is a binary tree such that, • the nodes of a left sub-tree contain elements that are less than the element stored at the local root (or is empty); • the nodes of a right sub-tree contain elements that are greater than the element stored at the local root (or is empty). 5 8 15 12 29 2 7 1 4 50 13 The definition precludes duplicate values.
Binary search tree Implementing a binary search tree, what is needed? That's right, we need a class Node . What are its instance variables? Its instance variables are value , left and right . What are the types of these variables? value should be Comparable , left and right should be of type Node .
Observations A leaf is a Node such that both its descendant reference variables ( left and right ) are null .


Meet Melinda and her beautiful family.
Melinda was absolutely glowing for her maternity session this past week. This family has been waiting for this little one, and I can't wait to see what an adorable baby it will be!


12/4/2012 – It was a fitting way of finally overtaking Garry Kasparov's record, as Magnus Carlsen and Gawain Jones played a wild game. Jones sacrificed his queen for play, but Carlsen held fast and is now at 2857.4. Levon Aronian scored the next win, over Luke McShane in a thrilling endgame as he fought past four connected passed pawns. Illustrated report with realtime postgame analysis.
In another incredibly entertaining round, we had some of the craziest material imbalances seen at top level chess! Nothing creates excitement over the board like material imbalance.
A young fan was given the honor of playing the first move, and played 1.d4 for Magnus.
Carlsen then retracted the move before starting and chose 1.e4 instead.
Carlsen-Jones 1-0: In a Maroczy bind structure, things got interesting when Jones sacrificed a queen for a knight and a bishop and positional compensation. However, with very accurate play and some seemingly awkward moves, Carlsen slowly but surely got himself out of the bind and the ensuing material advantage was just too much.
Carlsen acknowledged he took as a serious move, and by no means dismissed it.
Nakamura-Adams ½-½: Nakamura tried and tried and tried to push an unpushable position. Despite having the pair of bishops, it was simply not sufficient and Adams held a draw.
he too then decided 1.d4 was going to be his choice.
Anand-Kramnik ½-½: Definitely the low point of the round. Kramnik neutralized Anand who goes 17 straight classical games without victory and was forced to agree to a boring draw.
McShane-Aronian 1-0: This game saw an incredibly complex material balance. In a fantastic endgame White had a Rook and Knight and four(!) passed pawns against Black's Queen and Bishop. However, there were also a-pawns for both players, and after Aronian won his opponent's he had the edge with his now passed a-pawn. Although it looked scary for both sides, at the very end Black's two queens proved to be too much for White's pieces and some cool maneuvering led directly to checkmate. Awesome game!
the Englishman pushed his four passed pawns forward.


Seven Mukhi Rudraksha bead eliminate the malefic causes of Saturn (Shani) and ailment like, obstacles, desperation, interruption, insufficiency, concern etc. Seven Faced Rudraksha Bead help, to lead a healthy and wealthy life, to reduce mental illness, to remove troubles out of business and Profession, to Protection from untimely death and accidents. . It has Seven natural marked lines.
AstroCent provide genuine and pure Energised Seven Mukhi Rudraksh.


New waves of technology are gaining momentum, and one, in particular, is the security token movement. If you are even remotely familiar with the blockchain industry, then you've most likely heard of ICOs (initial coin offerings), which were all the rage throughout 2017 and 2018, raising over $10 billion dollars in those two years. Unfortunately, the ICO movement was also filled with a large amount of hype, which resulted in unfinished projects, scammers, and disappointed investors. Some project owners even ran off with funds, causing investors to be at a total loss, with little legal ramifications. But, it seems we have a solution now – security token offerings (STOs), which are expected to be a hit throughout 2019.
3 What Exactly is a Security?
4 Then, What is a Security Token?
5 Will STOs make ICOs obsolete?
6 Where Can I Keep Up to Date on the Latest STOs?
A utility token is a token issued through initial coin offerings. In short, initial coin offerings are a fundraising mechanism used by projects to fund their business and development efforts by selling tokens.
Utility tokens are meant to provide utility, which means that from a legal and business standpoint, utility tokens are not sold with the expectation of profits. Uses of utility tokens can be for purchase discounts, priority on support, priority on gaining access to new features, and others.
What history has shown, is that in many cases, these utility tokens sold by ICOs didn't provide much utility at all.
So, why did investors buy into ICOs? Well, investors purchased tokens with the expectation that the tokens will be listed on an exchange, increase in price, and as a result, they hoped to profit.
This is where things get ugly; investors and regulators are not on the same page. Companies are (officially) not selling profitable assets, while people are buying them for potential profits. The reason for this is because, oddly enough, some people did make lots of money from investing in these tokens. But, unless you understand some fundamental cryptocurrency investment strategies, it's mostly luck of the draw.
To reiterate, although the token should have inherent utility within the application, most utility tokens did not have any obvious use case (utility) for the business, which left investors stuck with useless tokens.
These tokens are purely speculative, and should only be purchased if you plan to use the project's software or product. Otherwise, you are gambling on the token's price increasing, which is completely separated from the success of the business. Utility tokens do not grant any ownership in the company to holders, do not pay dividends to investors, and are not legally considered a security, which brings us to our next point.
A security is a fungible financial instrument (such as stock) which is sold to investors. Investors purchase this security with the expectation to receive a return on their investment from the company's success, such as investing in a company and receiving stock. Securities are bound to regulatory rules and obligations to their investors, whereas utility tokens from ICOs are exempt from these rules.
There is a famous test called the Howey Test developed in the 1940s to define if an investment contract is a security or not. There are many blurry lines defining what makes an asset a security, and even today, some things are up to debate, especially in the cryptocurrency market. Overall, if investors invest to make profits, then it may very well be a security.
Then, What is a Security Token?
A security token is a tokenized security. Seems obvious, but what does that really mean?
Well, unlike a utility token, you are investing directly in the company or company assets. This means that just like investing in public stocks, you may be eligible to receive dividends, revenue share on profits, or part ownership in the company which can include voting rights.
Additionally, projects looking to issue their own security tokens must regulate with governments just like any traditional company would have to. This means they may not be able to accept investments from all investors, might have a minimum requirement for amounts to invest, and will require all investors to go through a KYC/AML process.
The goal of STOs is to give investors the peace of mind that, unlike ICO projects, these projects are conscious of regulations and are obligated to update their clients on revenue and pay dividends accordingly.
The beauty of blockchain technology is that we can automate certain functions, to offer a more fluid ecosystem for trading. These security tokens are tokenized assets which have confirmed ownership by investors on the blockchain. All token ownership, KYC/AML rules, and more are typically programmed into the token and/or related smart contracts. It's pretty crazy.
This means that while any two individuals can trade utility tokens between one another, a security token between two parties may fail if one of the investors fails the KYC/AML or other rules, which are programmatically entered into the system. There may also be a whitelist of permitted addresses which a smart contract checks against to be sure that the token can be sent to the recipient.
Examples of STOs can be any company like you see on the stock market, in addition to real-estate backed companies, gold and commodity-based companies, and more. Some projects are launching an STO with the security being backed by masternode or staking services done by the firm. As they profit from securely staking for investors, you get a share of their pie!
Will STOs make ICOs obsolete?
In my opinion, no. There are some valid use-cases for utility tokens, especially if people are comfortable investing in the token for its utility. Loyalty programs, discounts on purchases, and priority for support are all valid use-cases for utility tokens.
Surprisingly, I believe that utility tokens and security tokens can complement each other very well. For example, a project can issue security tokens, in addition to giving free utility tokens to all security token holders. If a real-estate backed STO issues security tokens, then perhaps they can also give free utility tokens to all holders giving them priority support or access to certain features of their platform. The point here is that utility tokens can further incentivize and add to the overall experience that companies can offer.
Where Can I Keep Up to Date on the Latest STOs?
This stuff is new, so there are not that many resources yet, but I recommend checking out the Security Token Network. They have an awesome list of STOs upcoming and active STOs, in addition to educational articles and current events on the industry. I highly recommend checking them out to familiarize yourself with the types of companies launching STOs, and to become acquainted with the industry.
Michael is the co-founder of doiownashitcoin, and has been deeply involved in the crypto space since 2014. Nowadays, he likes to educate his friends and newcomers through his technical approach.


text:
Two out and two in once again – SRA maintains City bias on its board
Posted by Legal Futures
Rowlands: wealth of insight, experience and expertise
The Solicitors Regulation Authority has again maintained the City bias on its board with its latest batch of appointments.
In all, five new members will take their seats around the table from January, of which two are solicitors: Geoff Nicholls, a senior partner at City firm Freshfields Bruckhaus Deringer, and City-trained Barry Matthews, director of legal affairs and third party sales at broadcaster ITV.
They replace Norton Rose partner Martin Coleman and Dentons consultant Cindy Leslie.
This time last year two outgoing City-based board members were replaced by two more as well.
Of the three other solicitor board members, one is also a City lawyer – Moni Mannings, a finance partner at Olswang – and the remaining two are Chris Randall, chief executive of 30-partner multi-office Sussex firm Mayo Wynne Baxter, and former Law Society president Paul Marsh, a conveyancer who is a consultant with 15-partner Downs Solicitors in Surrey.
Mr Matthews founded the Legal Social Mobility Partnership in 2014, which aims to promote diversity in the legal profession.
The board has a lay majority and the three new lay members are:
Accountant Sharon Darcy, a council member of Which? and, among other things, one of the first lay members to be appointed to the House of Commons' Committee on Standards;
Dame Denise Platt DBE, who has a professional background in social care and whose "portfolio of interests" include being chair of the National AIDS Trust and a member of the General Medical Council; and
Deep Sagar, a non-executive director and management consultant who chairs the National Police Chiefs Council's audit and assurance board and has been member of the Law Society of Scotland's professional practice committee and the Health Professions Council. The SRA said Mr Sagar "has long and varied experience with solicitors. He chaired the Leasehold Advisory Service – largely staffed by solicitors – recently, for example".
The trio replace Graham Chisnall, Bill Galvin and Peter Phippen.
SRA chair Enid Rowlands said: "I'm delighted to announce that we have five such distinguished appointees joining our board in the New Year. They will bring a wealth of insight, experience and expertise and I am looking forward to working with them to protect the public and set the standards for solicitors, as we reform our regulatory model."
Six of the 15 members of the SRA board are women.


text:
Filip Cveticanin
Filip Cveticanin was born in Serbia in 1996 and came has a young boy to Portugal. Sport runs in the family with his father a former handball coach and his mother a physical education teacher. He started to play volleyball at the age of 14 in GDC Gueifaes and transferred to Castelo Maia GC where he stayed some years. He's been playing in SL Benfica since 2017/18 with whom he won 2 Portuguese cups and this year national championship. As a 199-cm middle-blocker, he's a good attacker and blocker with wide margin of evolution. He needs to be more committed and willing, physically and mentally and give his best in all the moments. In his last participation for the junior national team, at the European Qualification for the 2015 World Championship, he started to show a great personality, with more competitiveness. In the same year he debuted in the World League and showed great ambition and will, entering in the initial line-up in some matches, and with a great evolution in his physical and mental capacities. He has a very aggressive jump tennis service and he's a good tactical player. In 2016, he has been in the World League final phase of Group 2 and also in the European Qualification to the European 2017. In 2017 and 2018 he was in all the competitions and success of the National Team, such as securing a spot in the 2019 EuroVolley finals and wining in 2018 the Challenger Cup that granted the team access to this year's edition of the VNL
Position Middle blocker
International Debut Guadalajara, ESP
Club Debut GDC Gueifaes
Current Club SL Benfica


text:
CloseExplore
Opportunity Agenda
Fulfilling America's Pledge – Buckeye Cities Blaze a Path for Renewables
Cities across the U.S. are leading the way when it comes to renewable energy procurement, and for good reason. Not only are renewable energy technologies cost competitive with traditional fossil fuel sources, but they also boast significant environmental and health benefits for local communities. And while the thought of renewables may conjure images of places like sunny California or windy Texas, two of the nation's leading cities call the Buckeye State home. That's no surprise when you consider a recent poll that found that 70% of conservatives in Ohio want a majority of their energy to come from renewable sources. Cincinnati and Columbus are working to make that dream a reality.
Fulfilling America's Pledge – Climate Mayors, 20 Leading Cities, and New Partnerships Lead America's Electric Transportation Future
This past month the United States sold its one-millionth electric car (more than 4 million have been sold globally). The event marks a significant milestone and demonstrates that mobility in the U.S. is on the threshold of a major technological transition to an electric mobility future. This monumental transportation transition is coupled with unprecedented levels of subnational engagement on climate change. Leadership on climate change and clean transportation is increasingly coming from states and cities who have come forward to uphold the Paris Climate Accord in the face of federal resistance.
Fulfilling America's Pledge – How Cities are Taking Charge in the Next Wave of Clean Energy Procurement
Cities in the United States are uniquely positioned to spur growth in demand for renewable energy procurement, accelerate the transition to a clean energy system, and provide visible and practical examples for the country as whole. By demonstrating to states, regions, and the federal government that it is possible to take practical, actionable steps to decarbonize electricity use, city leaders have the potential to inspire impact far beyond their limited jurisdictions. (Case in point: the Washington, D.C., City Council just unanimously voted "yes" to require 100 percent of the district's electricity to come from renewable sources by 2032—against a background of political gridlock at the federal level.)
Fulfilling America's Pledge on Climate Change Means Turning Data-Driven Research into Real World Action
In the United States, as in every country around the world, opportunities for climate leadership exist at every level of governance. So despite what the
headlines may say about current inaction on climate change at the federal level, businesses, cities, and states are laying the groundwork for America's low carbon future. The thousands of day-to-day investment decisions made by businesses, local solutions implemented by mayors and city councils, and win-win energy and environmental policies set by state governors and legislatures are adding up.
U.S. election swept in new climate leadership
Last week, the U.S. midterm election flipped the House of Representatives, six state legislative chambers, seven governorships, and a myriad of other seats across the country, thus sweeping in a cohort of new leaders at state, city, and local levels who have committed to ambitious climate action. This wave of new leaders adds to the already large list of city, state, and other elected leaders who have incorporated climate change into their platform: acknowledging scientific consensus, pledging to uphold the Paris Agreement, and investing in clean energy.
© 2020 Bloomberg Philanthropies Support LLC
americaspledge@bloomberg.org


Offices across the UK including London, Leicester, Stamford, Lincoln, Chester, Wigan and Wakefield.
Quadrant Building Control is an established, leading private sector Building Control service approved by the Construction Industry Council (CIC).
Formed in 2007, Quadrant Building Control has offices in London, Leicester, Stamford, Lincoln, Chester, Wigan and Wakefield. We have plans to open new offices across the UK in 2018. Our four directors (Joe Campion, Keith Day, Nick Ellson and Paul Knight) have significant private sector and Local Authority Building Control experience in all construction sectors. Our directors are supported by a team of building control professionals who adopt a friendly, common sense approach to building control.
Our aim is twofold: client satisfaction and the best possible built environment.
We pride ourselves on providing a first-class Building Control service for both commercial clients and residential clients; as a result we enjoy high levels of repeat business and client recommendations.
Quadrant Building Control is committed to maintaining high service standards to meet all of our clients' Building Control requirements and aspirations.
Our clients praise our professionalism and efficiency, expert knowledge and experience. We strive always to be helpful, reliable, reassuring and trustworthy.


text:
Everything You Need to Know About Honeymooning in St. Kitts and Nevis
These islands are a must-see for beach lovers
Kathryn Romeyn
Kathryn Romeyn has a degree in print journalism from Northeastern University. She is a seasoned travel writer with over 10 years of experience.
It may not be one of the most known Caribbean countries, but the dual-island nation of St. Kitts and Nevis in the West Indies is certainly one of the most picturesque. And because it's a commonwealth of the U.K., you'll definitely be able to speak the language (they were some of the first islands to be settled and had the first British and French colonies in the Caribbean). Here you won't find the massive sprawl of, say, Nassau. Instead, boutique-sized properties with an excess of charm and beauty are more common. And because they're getting increasingly popular—thanks in part, perhaps, to news of Prince Harry traveling to Nevis to save baby sea turtles—Delta has recently added more direct flights.
Fortunately both islands were mostly spared by October's hurricanes that devastated so much of the region. For that reason it's an attractive alternative to somewhere like St. Barths that was harder hit and is still in recovery mode. Speaking of, hurricane season runs from June to November, leaving uncertainty regarding storms that might not make the best honeymoon weather. The other half of the year, December through April, is prime time—make sure to book early, especially if going during February's winter Carnival celebrations. And May and June tend to be less expensive and less busy, yet without much rain. Temps year-round stay at about a perfect 80.
Selecting a destination may depend on the hotel, or you can let the island guide you. The larger of the two is St. Kitts, famous for its beaches of white, gray, and black sand, mountains coated in rainforest, and even a volcano to hike. It also has several historical attractions, like the capital Basseterre with colonial-era buildings and a plaza with a Victorian clock tower that harks to Piccadilly Circus, and Brimstone Hill Fortress National Park, which was built in the 18th century and has panoramic Caribbean views. For its part, Nevis—the birthplace of Alexander Hamilton—has Georgian-style architecture as well, along with a few quaint museums (the Nevis Sports Museum might call to fans of cricket), freshwater pools for rainforest bathing, and palm-lined sandy beaches for snorkeling (Pinney's, Oualie, and Lover's Beach are a few of the best).
The Four Seasons Resort Nevis is an ideal place to lay your newlywed heads. It's surrounded by sugary beaches and rainforest views, not to mention that jewel-tone water that always seems to be just the right temperature. If you want to go beyond the standard honeymoon activities (not that there's anything wrong with those) book their Dive and Dine excursion, which entails scuba diving with a dive master and a chef for epic underwater scenery, plus the opportunity to lasso your own lobsters, which chef will teach you to grill back on the mainland for a beachside lunch in a cabana. Another option, Paradise Beach Nevis speaks to lobster lovers with its bakes on their own private beach, which is easily accessible from its five new romantic beach houses that sit on stilts above the powdery sand (or choose one of seven thatched-roof villas).
See more: The 6 Most Luxurious Honeymoon Suites in Thailand
Over on St. Kitts, the biggest news is the opening of the Caribbean's first Park Hyatt, the Park Hyatt St. Kitts. Each of the 126 rooms and suites are sustainably designed and highlight bright blue Caribbean views, with features such as balconies and terraces, along with deep soaking tubs perfect for two. Along with a pair of pools and the expansive first Miraval Life in Balance Spa in the Caribbean (definitely a place you two should spend some downtime) the tony resort boasts an ocean-to-table restaurant, Fisherman's Village; the Stone Barn (for adults only), with sophisticated multicourse tasting menus; and the Great House restaurant, complete with a rum bar, chef's table, and plenty of space for intimate dinners. Another option on the big island: St. Kitts Marriott Resort, a tropical oasis on Frigate Bay that offers Kittitian cuisine, bamboo massages, and a sailing trip to Nevis.
The Top 50 Honeymoon Destinations for 2020
Everything You Need to Know About Honeymooning in Iceland
Escape the Cold with These Caribbean Hot Spots
10 Reasons Nassau is the Perfect Destination Wedding Island
Brides Honeymoon Awards 2019: The Most Romantic Spots To Travel
Right Time, Right Place: The Best Honeymoon Destinations by Month
18 Easy but Epic Mini Moon Destinations
Why Guadeloupe Should Be High on Your Honeymoon List
25 Islands That Guarantee A Totally Dreamy Honeymoon
2019's Most Luxe Honeymoon Destinations
Here's How to Plan a Honeymoon in Barbados
Get Ready to Plunge! 22 Scuba Diving Excursion Honeymoons
2015 BRIDES Best Honeymoons: The World's 20 Most Romantic Destinations
9 Romantic Valentine's Day Getaway Ideas for Every Kind of Couple
7 Stunning Caribbean Resorts to Escape the Cold
How to Honeymoon in Jamaica—Beyond the Beach


text:
'use strict';

var _ = require('lodash');
import Auth from '../lib/auth';
var allow = require('./proxy_allows').allow;
var debug = require('debug')('sdk:auth');

var JsonWebTokenError = require('jsonwebtoken/lib/JsonWebTokenError');

/**
 *
 * 过滤代理(proxy)的影响,获取用户真实 IP,由于代理有 slb、nginx 多层,
 * 用 trust proxy 不合适。
 *
 * 需要与 nginx 配置配合使用
 *
 */
function middleware() {

    return function checkAuthMiddleware(req, res, next) {

        let accessToken = req.query['access-token'] || _.get(req, 'headers.x-auth-token', req.cookies.token);
        // 支持从 query 传 token(所以必须用 HTTPS),query 优先级最高

        // @TODO 确定并增强安全性

        if (accessToken) {

            let user = null;
            try {
                user = Auth.verify(accessToken);

                if (!user.uid && !user.hb_uid) {
                    throw new JsonWebTokenError();
                }

                // debug('@check_auth user', user);
            }
            catch (err) {

                // debug('@check_auth catch', err);

                let allowAccessWithoutUser = allow.some((control) => {
                    let reg = new RegExp(control.path);

                    let t =  reg.test(req.path);

                    debug(req.path, reg, t);

                    return t;

                });

                if (allowAccessWithoutUser) {
                    return next();
                }

                next(err);
            }

            if (user) {
                req.user = user;
                req.accessToken = accessToken;

                // 设置后端需要的 header
                req.headers['user-id'] = req.user.uid;

                req.headers['dealer-id'] = _.get(req.user, 'dealer_id', '');
                req.headers['dealer-code'] = _.get(req.user, 'dealer_code', '');
                req.headers['dealer-user-id'] = _.get(req.user, 'duid', '');

                req.headers['identifier'] = req.user.dealer_id + '-' + req.user.duid;

                req.headers['api-auth-method'] = 'token';

            }

        }

        next();

    };

}

function errorHandler(err, req, res, next) {

    let errName = _.get(err, 'name');

    if (errName == 'JsonWebTokenError') {
        // token 解析出错
        res.status(401);
        return res.json({
            code: -1,
            message: 'Token 不合法',
            ext: err.message
        });
    }
    else if (errName == 'TokenExpiredError') {
        // token 解析出错
        res.status(401);
        return res.json({
            code: -2,
            message: 'Token 已过期',
            ext: err.message
        });
    }

    return next(err);
}

export default {
    middleware: middleware,
    errorHandler: errorHandler
};