1. Araxis Merge ファイル比較レポート

このレポートは Araxis Merge11/20/2017 2:20:34 PM GMT Standard Time によって作成されました。Merge に関する情報については www.araxis.com をご覧ください。このレポートは XHTML と CSS2 を使用し、最新の標準基準に準拠したブラウザでご覧になれます。このレポートを印刷するための最適条件は、背景の色とイメージの印刷を可能にして、印刷の向きは横を使用します。

1.1 ファイルの比較

# ロケーション ファイル 更新日時
1 Mon Nov 20 14:20:34 2017 UTC
2 C:\Merge Test Files\8.5.23\java\org\apache\catalina\authenticator\jaspic AuthConfigFactoryImpl.java Thu Sep 28 11:32:16 2017 UTC

1.2 比較の概要

説明 第1ファイルと第2ファイル
テキスト ブロック
変更なし 0 0
変更箇所 0 0
挿入箇所 1 495
削除箇所 0 0

1.3 比較のオプション

余白 連続した空白文字を 1 文字として扱う
大文字/小文字 大文字と小文字の相違を意味のあるものとして扱う
行終端文字 行終端文字(CRLF 文字)の相違を無視する
CR/LF 文字 比較の詳細に示されない

1.4 有効な正規表現

有効な正規表現はありません。

1.5 比較の詳細

        1   /**
        2    *  Licens ed to the  Apache Sof tware Foun dation (AS F) under o ne or more
        3    *  contri butor lice nse agreem ents.  See  the NOTIC E file dis tributed w ith
        4    *  this w ork for ad ditional i nformation  regarding  copyright  ownership .
        5    *  The AS F licenses  this file  to You un der the Ap ache Licen se, Versio n 2.0
        6    *  (the " License");  you may n ot use thi s file exc ept in com pliance wi th
        7    *  the Li cense.  Yo u may obta in a copy  of the Lic ense at
        8    *
        9    *     htt p://www.ap ache.org/l icenses/LI CENSE-2.0
        10    *
        11    *  Unless  required  by applica ble law or  agreed to  in writin g, softwar e
        12    *  distri buted unde r the Lice nse is dis tributed o n an "AS I S" BASIS,
        13    *  WITHOU T WARRANTI ES OR COND ITIONS OF  ANY KIND,  either exp ress or im plied.
        14    *  See th e License  for the sp ecific lan guage gove rning perm issions an d
        15    *  limita tions unde r the Lice nse.
        16    */
        17   package or g.apache.c atalina.au thenticato r.jaspic;
        18  
        19   import jav a.io.File;
        20   import jav a.lang.ref lect.Const ructor;
        21   import jav a.lang.ref lect.Invoc ationTarge tException ;
        22   import jav a.util.Arr ayList;
        23   import jav a.util.Col lections;
        24   import jav a.util.Has hMap;
        25   import jav a.util.Lis t;
        26   import jav a.util.Map ;
        27   import jav a.util.Map .Entry;
        28   import jav a.util.con current.Co ncurrentHa shMap;
        29   import jav a.util.con current.Co pyOnWriteA rrayList;
        30  
        31   import jav ax.securit y.auth.mes sage.confi g.AuthConf igFactory;
        32   import jav ax.securit y.auth.mes sage.confi g.AuthConf igProvider ;
        33   import jav ax.securit y.auth.mes sage.confi g.Registra tionListen er;
        34  
        35   import org .apache.ca talina.Glo bals;
        36   import org .apache.ca talina.aut henticator .jaspic.Pe rsistentPr oviderRegi strations. Provider;
        37   import org .apache.ca talina.aut henticator .jaspic.Pe rsistentPr oviderRegi strations. Providers;
        38   import org .apache.ju li.logging .Log;
        39   import org .apache.ju li.logging .LogFactor y;
        40   import org .apache.to mcat.util. res.String Manager;
        41  
        42   public cla ss AuthCon figFactory Impl exten ds AuthCon figFactory  {
        43  
        44       privat e static f inal Log l og = LogFa ctory.getL og(AuthCon figFactory Impl.class );
        45       privat e static f inal Strin gManager s m = String Manager.ge tManager(A uthConfigF actoryImpl .class);
        46  
        47       privat e static f inal Strin g CONFIG_P ATH = "con f/jaspic-p roviders.x ml";
        48       privat e static f inal File  CONFIG_FIL E =
        49                new File (System.ge tProperty( Globals.CA TALINA_BAS E_PROP), C ONFIG_PATH );
        50       privat e static f inal Objec t CONFIG_F ILE_LOCK =  new Objec t();
        51  
        52       privat e static f inal Strin g[] EMPTY_ STRING_ARR AY = new S tring[0];
        53  
        54       privat e static S tring DEFA ULT_REGIST RATION_ID  = getRegis trationID( null, null );
        55  
        56       privat e final Ma p<String,R egistratio nContextIm pl> layerA ppContextR egistratio ns =
        57                new Conc urrentHash Map<>();
        58       privat e final Ma p<String,R egistratio nContextIm pl> appCon textRegist rations =
        59                new Conc urrentHash Map<>();
        60       privat e final Ma p<String,R egistratio nContextIm pl> layerR egistratio ns =
        61                new Conc urrentHash Map<>();
        62       // Not e: Althoug h there wi ll only ev er be a ma ximum of o ne entry i n this
        63       //        Map, us e a Concur rentHashMa p for cons istency
        64       privat e volatile  Map<Strin g,Registra tionContex tImpl> def aultRegist ration =
        65                new Conc urrentHash Map<>(1);
        66  
        67  
        68       public  AuthConfi gFactoryIm pl() {
        69           lo adPersiste ntRegistra tions();
        70       }
        71  
        72  
        73       @Overr ide
        74       public  AuthConfi gProvider  getConfigP rovider(St ring layer , String a ppContext,
        75                Registra tionListen er listene r) {
        76           Re gistration ContextImp l registra tionContex t =
        77                    find Registrati onContextI mpl(layer,  appContex t);
        78           if  (registra tionContex t != null)  {
        79                Registra tionListen erWrapper  wrapper =  new Regist rationList enerWrappe r(
        80                         layer, app Context, l istener);
        81                registra tionContex t.addListe ner(wrappe r);
        82                return r egistratio nContext.g etProvider ();
        83           }
        84           re turn null;
        85       }
        86  
        87  
        88       @Overr ide
        89       public  String re gisterConf igProvider (String cl assName,
        90                @Suppres sWarnings( "rawtypes" ) Map prop erties, St ring layer , String a ppContext,
        91                String d escription ) {
        92           St ring regis trationID  =
        93                    doRe gisterConf igProvider (className , properti es, layer,  appContex t, descrip tion);
        94           sa vePersiste ntRegistra tions();
        95           re turn regis trationID;
        96       }
        97  
        98  
        99       @Suppr essWarning s("uncheck ed")
        100       privat e String d oRegisterC onfigProvi der(String  className ,
        101                @Suppres sWarnings( "rawtypes" ) Map prop erties, St ring layer , String a ppContext,
        102                String d escription ) {
        103           if  (log.isDe bugEnabled ()) {
        104                log.debu g(sm.getSt ring("auth ConfigFact oryImpl.re gisterClas s",
        105                         className,  layer, ap pContext)) ;
        106           }
        107           Cl ass<?> cla zz;
        108           Au thConfigPr ovider pro vider = nu ll;
        109           tr y {
        110                clazz =  Class.forN ame(classN ame, true,  Thread.cu rrentThrea d().getCon textClassL oader());
        111           }  catch (Cla ssNotFound Exception  e) {
        112                // Ignor e so the r e-try belo w can proc eed
        113           }
        114           tr y {
        115                clazz =  Class.forN ame(classN ame);
        116                Construc tor<?> con structor =  clazz.get Constructo r(Map.clas s, AuthCon figFactory .class);
        117                provider  = (AuthCo nfigProvid er) constr uctor.newI nstance(pr operties,  null);
        118           }  catch (Cla ssNotFound Exception  | NoSuchMe thodExcept ion | Inst antiationE xception |
        119                    Ille galAccessE xception |  IllegalAr gumentExce ption | In vocationTa rgetExcept ion e) {
        120                throw ne w Security Exception( e);
        121           }
        122  
        123           St ring regis trationID  = getRegis trationID( layer, app Context);
        124           Re gistration ContextImp l registra tionContex tImpl = ne w Registra tionContex tImpl(
        125                    laye r, appCont ext, descr iption, tr ue, provid er, proper ties);
        126           ad dRegistrat ionContext Impl(layer , appConte xt, regist rationID,  registrati onContextI mpl);
        127           re turn regis trationID;
        128       }
        129  
        130  
        131       @Overr ide
        132       public  String re gisterConf igProvider (AuthConfi gProvider  provider,  String lay er,
        133                String a ppContext,  String de scription)  {
        134           if  (log.isDe bugEnabled ()) {
        135                log.debu g(sm.getSt ring("auth ConfigFact oryImpl.re gisterInst ance",
        136                         provider.g etClass(). getName(),  layer, ap pContext)) ;
        137           }
        138           St ring regis trationID  = getRegis trationID( layer, app Context);
        139           Re gistration ContextImp l registra tionContex tImpl = ne w Registra tionContex tImpl(
        140                    laye r, appCont ext, descr iption, fa lse, provi der, null) ;
        141           ad dRegistrat ionContext Impl(layer , appConte xt, regist rationID,  registrati onContextI mpl);
        142           re turn regis trationID;
        143       }
        144  
        145  
        146       privat e void add Registrati onContextI mpl(String  layer, St ring appCo ntext,
        147                String r egistratio nID, Regis trationCon textImpl r egistratio nContextIm pl) {
        148           Re gistration ContextImp l previous  = null;
        149  
        150           //  Add the r egistratio n, noting  any regist ration it  replaces
        151           if  (layer !=  null && a ppContext  != null) {
        152                previous  = layerAp pContextRe gistration s.put(regi strationID , registra tionContex tImpl);
        153           }  else if (l ayer == nu ll && appC ontext !=  null) {
        154                previous  = appCont extRegistr ations.put (registrat ionID, reg istrationC ontextImpl );
        155           }  else if (l ayer != nu ll && appC ontext ==  null) {
        156                previous  = layerRe gistration s.put(regi strationID , registra tionContex tImpl);
        157           }  else {
        158                previous  = default Registrati on.put(reg istrationI D, registr ationConte xtImpl);
        159           }
        160  
        161           if  (previous  == null)  {
        162                // No ma tch with p revious re gistration  so need t o check li steners
        163                // for a ll less sp ecific reg istrations  to see if  they need  to be
        164                // notif ied of thi s new regi stration.  That there  is no exa ct match
        165                // with  a previous  registrat ion allows  a few sho rt-cuts to  be taken
        166                if (laye r != null  && appCont ext != nul l) {
        167                    // N eed to che ck existin g appConte xt registr ations
        168                    // ( and layer  and defaul t)
        169                    // a ppContext  must match
        170                    Regi strationCo ntextImpl  registrati on =
        171                             appCon textRegist rations.ge t(getRegis trationID( null, appC ontext));
        172                    if ( registrati on != null ) {
        173                         for (Regis trationLis tenerWrapp er wrapper  : registr ation.list eners) {
        174                             if (la yer.equals (wrapper.g etMessageL ayer()) &&
        175                                      appConte xt.equals( wrapper.ge tAppContex t())) {
        176                                 re gistration .listeners .remove(wr apper);
        177                                 wr apper.list ener.notif y(wrapper. messageLay er, wrappe r.appConte xt);
        178                             }
        179                         }
        180                    }
        181                }
        182                if (appC ontext !=  null) {
        183                    // N eed to che ck existin g layer re gistration s
        184                    // ( and defaul t)
        185                    // N eed to che ck registr ations for  all layer s
        186                    for  (Registrat ionContext Impl regis tration :  layerRegis trations.v alues()) {
        187                         for (Regis trationLis tenerWrapp er wrapper  : registr ation.list eners) {
        188                             if (ap pContext.e quals(wrap per.getApp Context()) ) {
        189                                 re gistration .listeners .remove(wr apper);
        190                                 wr apper.list ener.notif y(wrapper. messageLay er, wrappe r.appConte xt);
        191                             }
        192                         }
        193                    }
        194                }
        195                if (laye r != null  || appCont ext != nul l) {
        196                    // N eed to che ck default
        197                    for  (Registrat ionContext Impl regis tration :  defaultReg istration. values())  {
        198                         for (Regis trationLis tenerWrapp er wrapper  : registr ation.list eners) {
        199                             if (ap pContext ! = null &&  appContext .equals(wr apper.getA ppContext( )) ||
        200                                      layer !=  null && l ayer.equal s(wrapper. getMessage Layer()))  {
        201                                 re gistration .listeners .remove(wr apper);
        202                                 wr apper.list ener.notif y(wrapper. messageLay er, wrappe r.appConte xt);
        203                             }
        204                         }
        205                    }
        206                }
        207           }  else {
        208                // Repla ced an exi sting regi stration s o need to  notify tho se listene rs
        209                for (Reg istrationL istenerWra pper wrapp er : previ ous.listen ers) {
        210                    prev ious.liste ners.remov e(wrapper) ;
        211                    wrap per.listen er.notify( wrapper.me ssageLayer , wrapper. appContext );
        212                }
        213           }
        214       }
        215  
        216  
        217       @Overr ide
        218       public  boolean r emoveRegis tration(St ring regis trationID)  {
        219           Re gistration ContextImp l registra tion = nul l;
        220           if  (DEFAULT_ REGISTRATI ON_ID.equa ls(registr ationID))  {
        221                registra tion = def aultRegist ration.rem ove(regist rationID);
        222           }
        223           if  (registra tion == nu ll) {
        224                registra tion = lay erAppConte xtRegistra tions.remo ve(registr ationID);
        225           }
        226           if  (registra tion == nu ll) {
        227                registra tion =  ap pContextRe gistration s.remove(r egistratio nID);
        228           }
        229           if  (registra tion == nu ll) {
        230                registra tion = lay erRegistra tions.remo ve(registr ationID);
        231           }
        232  
        233           if  (registra tion == nu ll) {
        234                return f alse;
        235           }  else {
        236                for (Reg istrationL istenerWra pper wrapp er : regis tration.li steners) {
        237                    wrap per.getLis tener().no tify(wrapp er.getMess ageLayer() , wrapper. getAppCont ext());
        238                }
        239                return t rue;
        240           }
        241       }
        242  
        243  
        244       @Overr ide
        245       public  String[]  detachList ener(Regis trationLis tener list ener, Stri ng layer,  String app Context) {
        246           St ring regis trationID  = getRegis trationID( layer, app Context);
        247           Re gistration ContextImp l registra tionContex t = findRe gistration ContextImp l(layer, a ppContext) ;
        248           if  (registra tionContex t.removeLi stener(lis tener)) {
        249                return n ew String[ ] { regist rationID } ;
        250           }
        251           re turn EMPTY _STRING_AR RAY;
        252       }
        253  
        254  
        255       @Overr ide
        256       public  String[]  getRegistr ationIDs(A uthConfigP rovider pr ovider) {
        257           Li st<String>  result =  new ArrayL ist<>();
        258           if  (provider  == null)  {
        259                result.a ddAll(laye rAppContex tRegistrat ions.keySe t());
        260                result.a ddAll(appC ontextRegi strations. keySet());
        261                result.a ddAll(laye rRegistrat ions.keySe t());
        262                if (defa ultRegistr ation != n ull) {
        263                    resu lt.add(DEF AULT_REGIS TRATION_ID );
        264                }
        265           }  else {
        266                findProv ider(provi der, layer AppContext Registrati ons, resul t);
        267                findProv ider(provi der, appCo ntextRegis trations,  result);
        268                findProv ider(provi der, layer Registrati ons, resul t);
        269                findProv ider(provi der, defau ltRegistra tion, resu lt);
        270           }
        271           re turn resul t.toArray( EMPTY_STRI NG_ARRAY);
        272       }
        273  
        274  
        275       privat e void fin dProvider( AuthConfig Provider p rovider,
        276                Map<Stri ng,Registr ationConte xtImpl> re gistration s, List<St ring> resu lt) {
        277           fo r (Entry<S tring,Regi strationCo ntextImpl>  entry : r egistratio ns.entrySe t()) {
        278                if (prov ider.equal s(entry.ge tValue().g etProvider ())) {
        279                    resu lt.add(ent ry.getKey( ));
        280                }
        281           }
        282       }
        283  
        284  
        285       @Overr ide
        286       public  Registrat ionContext  getRegist rationCont ext(String  registrat ionID) {
        287           Re gistration Context re sult = def aultRegist ration.get (registrat ionID);
        288           if  (result = = null) {
        289                result =  layerAppC ontextRegi strations. get(regist rationID);
        290           }
        291           if  (result = = null) {
        292                result =  appContex tRegistrat ions.get(r egistratio nID);
        293           }
        294           if  (result = = null) {
        295                result =  layerRegi strations. get(regist rationID);
        296           }
        297           re turn resul t;
        298       }
        299  
        300  
        301       @Overr ide
        302       public  void refr esh() {
        303           lo adPersiste ntRegistra tions();
        304       }
        305  
        306  
        307       privat e static S tring getR egistratio nID(String  layer, St ring appCo ntext) {
        308           if  (layer !=  null && l ayer.lengt h() == 0)  {
        309                throw ne w IllegalA rgumentExc eption(
        310                         sm.getStri ng("authCo nfigFactor yImpl.zero LengthMess ageLayer") );
        311           }
        312           if  (appConte xt != null  && appCon text.lengt h() == 0)  {
        313                throw ne w IllegalA rgumentExc eption(
        314                         sm.getStri ng("authCo nfigFactor yImpl.zero LengthAppC ontext"));
        315           }
        316           re turn (laye r == null  ? "" : lay er) + ":"  + (appCont ext == nul l ? "" : a ppContext) ;
        317       }
        318  
        319  
        320       privat e void loa dPersisten tRegistrat ions() {
        321           sy nchronized  (CONFIG_F ILE_LOCK)  {
        322                if (log. isDebugEna bled()) {
        323                    log. debug(sm.g etString(" authConfig FactoryImp l.load",
        324                             CONFIG _FILE.getA bsolutePat h()));
        325                }
        326                if (!CON FIG_FILE.i sFile()) {
        327                    retu rn;
        328                }
        329                Provider s provider s = Persis tentProvid erRegistra tions.load Providers( CONFIG_FIL E);
        330                for (Pro vider prov ider : pro viders.get Providers( )) {
        331                    doRe gisterConf igProvider (provider. getClassNa me(), prov ider.getPr operties() ,
        332                             provid er.getLaye r(), provi der.getApp Context(),  provider. getDescrip tion());
        333                }
        334           }
        335       }
        336  
        337  
        338       privat e void sav ePersisten tRegistrat ions() {
        339           sy nchronized  (CONFIG_F ILE_LOCK)  {
        340                Provider s provider s = new Pr oviders();
        341                savePers istentProv iders(prov iders, lay erAppConte xtRegistra tions);
        342                savePers istentProv iders(prov iders, app ContextReg istrations );
        343                savePers istentProv iders(prov iders, lay erRegistra tions);
        344                savePers istentProv iders(prov iders, def aultRegist ration);
        345                Persiste ntProvider Registrati ons.writeP roviders(p roviders,  CONFIG_FIL E);
        346           }
        347       }
        348  
        349  
        350       privat e void sav ePersisten tProviders (Providers  providers ,
        351                Map<Stri ng,Registr ationConte xtImpl> re gistration s) {
        352           fo r (Entry<S tring,Regi strationCo ntextImpl>  entry : r egistratio ns.entrySe t()) {
        353                savePers istentProv ider(provi ders, entr y.getValue ());
        354           }
        355       }
        356  
        357  
        358       privat e void sav ePersisten tProvider( Providers  providers,
        359                Registra tionContex tImpl regi strationCo ntextImpl)  {
        360           if  (registra tionContex tImpl != n ull && reg istrationC ontextImpl .isPersist ent()) {
        361                Provider  provider  = new Prov ider();
        362                provider .setAppCon text(regis trationCon textImpl.g etAppConte xt());
        363                provider .setClassN ame(regist rationCont extImpl.ge tProvider( ).getClass ().getName ());
        364                provider .setDescri ption(regi strationCo ntextImpl. getDescrip tion());
        365                provider .setLayer( registrati onContextI mpl.getMes sageLayer( ));
        366                for (Ent ry<String, String> pr operty : r egistratio nContextIm pl.getProp erties().e ntrySet())  {
        367                    prov ider.addPr operty(pro perty.getK ey(), prop erty.getVa lue());
        368                }
        369                provider s.addProvi der(provid er);
        370           }
        371       }
        372  
        373  
        374       privat e Registra tionContex tImpl find Registrati onContextI mpl(String  layer, St ring appCo ntext) {
        375           Re gistration ContextImp l result;
        376           re sult = lay erAppConte xtRegistra tions.get( getRegistr ationID(la yer, appCo ntext));
        377           if  (result = = null) {
        378                result =  appContex tRegistrat ions.get(g etRegistra tionID(nul l, appCont ext));
        379           }
        380           if  (result = = null) {
        381                result =  layerRegi strations. get(getReg istrationI D(layer, n ull));
        382           }
        383           if  (result = = null) {
        384                result =  defaultRe gistration .get(DEFAU LT_REGISTR ATION_ID);
        385           }
        386           re turn resul t;
        387       }
        388  
        389  
        390       privat e static c lass Regis trationCon textImpl i mplements  Registrati onContext  {
        391  
        392           pr ivate Regi strationCo ntextImpl( String mes sageLayer,  String ap pContext,  String des cription,
        393                    bool ean persis tent, Auth ConfigProv ider provi der, Map<S tring,Stri ng> proper ties) {
        394                this.mes sageLayer  = messageL ayer;
        395                this.app Context =  appContext ;
        396                this.des cription =  descripti on;
        397                this.per sistent =  persistent ;
        398                this.pro vider = pr ovider;
        399                Map<Stri ng,String>  propertie sCopy = ne w HashMap< >();
        400                if (prop erties !=  null) {
        401                    prop ertiesCopy .putAll(pr operties);
        402                }
        403                this.pro perties =  Collection s.unmodifi ableMap(pr opertiesCo py);
        404           }
        405  
        406           pr ivate fina l String m essageLaye r;
        407           pr ivate fina l String a ppContext;
        408           pr ivate fina l String d escription ;
        409           pr ivate fina l boolean  persistent ;
        410           pr ivate fina l AuthConf igProvider  provider;
        411           pr ivate fina l Map<Stri ng,String>  propertie s;
        412           pr ivate fina l List<Reg istrationL istenerWra pper> list eners = ne w CopyOnWr iteArrayLi st<>();
        413  
        414           @O verride
        415           pu blic Strin g getMessa geLayer()  {
        416                return m essageLaye r;
        417           }
        418  
        419  
        420           @O verride
        421           pu blic Strin g getAppCo ntext() {
        422                return a ppContext;
        423           }
        424  
        425           @O verride
        426           pu blic Strin g getDescr iption() {
        427                return d escription ;
        428           }
        429  
        430  
        431           @O verride
        432           pu blic boole an isPersi stent() {
        433                return p ersistent;
        434           }
        435  
        436  
        437           pr ivate Auth ConfigProv ider getPr ovider() {
        438                return p rovider;
        439           }
        440  
        441  
        442           pr ivate void  addListen er(Registr ationListe nerWrapper  listener)  {
        443                if (list ener != nu ll) {
        444                    list eners.add( listener);
        445                }
        446           }
        447  
        448  
        449           pr ivate Map< String,Str ing> getPr operties()  {
        450                return p roperties;
        451           }
        452  
        453  
        454           pr ivate bool ean remove Listener(R egistratio nListener  listener)  {
        455                boolean  result = f alse;
        456                for (Reg istrationL istenerWra pper wrapp er : liste ners) {
        457                    if ( wrapper.ge tListener( ).equals(l istener))  {
        458                         listeners. remove(wra pper);
        459                    }
        460                }
        461                return r esult;
        462           }
        463       }
        464  
        465  
        466       privat e static c lass Regis trationLis tenerWrapp er {
        467  
        468           pr ivate fina l String m essageLaye r;
        469           pr ivate fina l String a ppContext;
        470           pr ivate fina l Registra tionListen er listene r;
        471  
        472  
        473           pu blic Regis trationLis tenerWrapp er(String  messageLay er, String  appContex t,
        474                    Regi strationLi stener lis tener) {
        475                this.mes sageLayer  = messageL ayer;
        476                this.app Context =  appContext ;
        477                this.lis tener = li stener;
        478           }
        479  
        480  
        481           pu blic Strin g getMessa geLayer()  {
        482                return m essageLaye r;
        483           }
        484  
        485  
        486           pu blic Strin g getAppCo ntext() {
        487                return a ppContext;
        488           }
        489  
        490  
        491           pu blic Regis trationLis tener getL istener()  {
        492                return l istener;
        493           }
        494       }
        495   }