Aggregate Script » History » Sprint/Milestone 1
Steven (eSHIFT) Uggowitzer, 21 July 2022 08:57 AM
1 | 1 | Steven (eSHIFT) Uggowitzer | h1. Aggregate Script |
---|---|---|---|
2 | |||
3 | {{>toc}} |
||
4 | |||
5 | The AMR data in a tracker module is exported using an ETL developed using R-Script. The steps are elaborated below. |
||
6 | |||
7 | * The Aggregate for RIS results developed on the Aggregate module. |
||
8 | * Program Indicators created to calculate the RIS results. Each of the program indicators are assigned with code formed by UID representing Data element and CategoryOptionCombo which are separated by Hyphen. The mapping of Data-Element and CategoryOptionCombo has been done on program indicator to reduce the Mapping work of ETL on R-scripts. |
||
9 | * The source for the assigned UIDs are Aggregate data module which is Destination Database. |
||
10 | * Each of the program indicators from tracker is representing one dimension of the data element on Aggregate module. |
||
11 | * R-Scripts is extracting the RIS report using APIs. The data extraction is divided into 4 different categories of data. The categories representing *Resistant, Intermediate, Susceptible* and *Not-tested*<notextile></notextile>. |
||
12 | * The report’s Organisation Units is fetched based on Organisation Unit group. User need to create an organization unit group for all facilities collected AMR data. |
||
13 | * R-Script blend the four categories of the report and is transformed to the CSV format which is acceptable by DHIS2. The *data element* and the *CategoryOptionCombo* is separate to have two columns of the data. |
||
14 | * The CSV file is imported in the DHIS2. So far, the Import is done via automated Curl command. The Curl for data import is set to run on a time set on Cronjob. It runs once in a month. |
||
15 | |||
16 | h2. Running the Aggregate ScriptLink to Running the Aggregate Script |
||
17 | |||
18 | |||
19 | h2. R-Script for Extraction and transformation of Data from program indicators to Aggregate RIS formLink to R-Script for Extraction and transformation of Data from program indicators to Aggregate RIS form |
||
20 | |||
21 | <pre><code class="r"> |
||
22 | library(RCurl) |
||
23 | |||
24 | library(tidyr) |
||
25 | |||
26 | |||
27 | |||
28 | # For Resistance -------- |
||
29 | |||
30 | Resistance <- getURL(paste0("https://amr-host.zm.dhis2.site/ohs/api/29/analytics.csv?dimension=pe:LAST_3_MONTHS&dimension=ou:OU_GROUP-lvbz0mkIFZU;AWn3s2RqgAN;utIjliUdjp8;J7PQPWAeRUk;KozcEjeTyuD;B1u1bVtIA92;dbTLdTi7s8F;SwwuteU1Ajk;q5hODNmn021;oPLMrarKeEY;g1bv2xjtV0w&dimension=dx:i71f1k6Ywde;KxQyBaNVWgC;Xk6MCCq2kzg;Z7TaC971IsX;baZQUWE0rFO;GJwNfMRp4EL;leW6h3Eple6;ZJa9rOeQkE2;b7w7gTWKUXZ;kT4dDT0NHMw;r9IrIM1V3Sx;frqTEQgrnbk;nBwIHoBbLrF;Xt9NX9Rh0fw;GfNVo7CssHk;TQQKwPDrwjk;yok8UJguhxJ;EoCTRsqqQ5M;O0pIw0kBdSn;O0pXsCrMt1E;X0g7rtM8P3X;ljZwDLquJcO;fYO7ZxJu2sZ;pzcQ6n1pcLJ;JFn7FxXavzU;Q9Qgq3nYpSP;YFsuusHcn26;DQPMqlJhoWm;Bxm9pOn5kl6;XY1c0GCIxhZ;JovFRVcpy6A;O0nV31FSGgZ;I4EucOsoVE3;AxLQmQhDHoC;Gq2xErOEyrE;BzGNBjXpmck;VPif922L8Ya;QJEikxjqlYP;lxgHMBUNUHl;V96DmUE7zMO;W2o4mOFxTuj;Ug6w2Wln6Vb;lzWp3t9V0oV;JsJFIo3C7z5;urFE2aMk8lj;lvmXRGVKZWa;Mk09Dsq0tMA;N6iaSLAUy1g;Hhv28risZ28;sTngPsOIb6o;nBOQt6Yer67;INZh9xg4jFb;efVDLeFKcDv;BfiY4gHGrin;l770nnL2NJK;pGc1UYaHqg8;EDftWGalKD7;EuLIpr1yX6I;ZFneNFHArkf;aMSfsX5C85q;bDXGA2lqXlk;yVWulHu8R2K;zSLu3UI76iU;GEWbLnlIYK5;jzHDpTnJW8O;TmeDAz5IFpo;jXhR1PIGYMT;UD3EOf1mNAj;upBBr3vnDuR;ZtitY01ETbs;KgFt0Q3mZxT;KBImbKOBglL;GcSr8JobxFZ;cYeVvQcAbqJ;QMRkBj7Xfwu;p56phNR5fiY;eXWqNo9OS9R;MMnM9163Ksg;YHbScScQ30h;sU0BC11JP0f;E4c7Xdzhjz7;FFzA1WidSuf;NnEYj9rdb8j;OXfeRjdO4rN;JXxmCy3cXH0;v2JHsDh1Tr1;wxKHTIuKd7U;B8jPEkHAsrp;piIaISz4dH4;SGl0md193h1;P2Kc9MVMrxZ;kKR7UL9xvTg;D3c6fZP4BF0;hMIeVlY7aNC;ayO1RMYxIMv;EjWyEomiGkb;DvhXH147Udr;kg6G53utwNy;bMU6ymDNfIC;GXzOn9OjTat;uwV4xxzG0N6;w8voRMKRK5o;S6yRhRhOP0t;frTB3cRciLv;WDKOG01PuaH;BBhJ811gdBh;sGY12KR57Cc;tB4myWwnaZ1;XlFGswbe7FL;x48hu3uKfnB;ujvCyU94rQE;Ty5W2wGjhtO;u8hvV4V2ZnK;YP2FmASQDYG;r0AQQyVS5GA;YI1CHzzDd2x;kDi18b7DgWi;kOqV3yBeqye;TM0YRhDN5z7;tFOy3mQa0Wp;gxWsXYOGr1A;yvuoMkSkKQ3;ubrfPpmfWJT;YLZiG343xpO;HogCPE1IgM0;BTDn3aK059M;zlfjL8trGAs;ClvXlm6Srtd;J8A93c5XZdk;Hjbfw7cKD6f;qFQNMfdDTZ8;jJUvCu7gsTZ;c4dXd7kiUTW;j1OsDEOnX0E;EEmEgSscHZo;fjhNTx5q41D;QTOVK6fd1zO;mLvGBD3IkQ9;PX28x18pNsn;e1HUbQ6O84C;Bef0Sp8uLHI;dLpsPmXfZxK;tN1vkI8QEv5;HFKtvDsnWGl;jHvGLv76IA7;z76mlay2t6j;BH0ehCFL5D7;z12GwGtS84X;u84T3p4Kg18;BTrI4DnaedM;bK6Wl3dqUo1;Kdr3oDVwiu7;imHqWk6ppSz;M0con4RGA4w;gOfbqxQxvgT;txPv34uwREH&displayProperty=NAME&outputIdScheme=CODE"), userpwd="UserName:Password", httpauth = 1L) |
||
31 | |||
32 | Resistance <- read.table(text = Resistance, sep =",", header = TRUE, stringsAsFactors = FALSE) |
||
33 | |||
34 | # head(Resistance) |
||
35 | |||
36 | |||
37 | |||
38 | |||
39 | |||
40 | |||
41 | |||
42 | # For Intermediate ------ |
||
43 | |||
44 | Intermediate <- getURL(paste0("https://amr-host.zm.dhis2.site/ohs/api/29/analytics.csv?dimension=pe:LAST_3_MONTHS&dimension=ou:OU_GROUP-lvbz0mkIFZU;AWn3s2RqgAN;utIjliUdjp8;J7PQPWAeRUk;KozcEjeTyuD;B1u1bVtIA92;dbTLdTi7s8F;SwwuteU1Ajk;q5hODNmn021;oPLMrarKeEY;g1bv2xjtV0w&dimension=dx:ngA4xOdqgxe;zZa0d8aOXnP;EMYG1Cd6IuY;PI2BHpiykg3;dRczpnCjpK0;mW6WyIHiDbW;LInPyvFbkui;XQEcH5oEZBb;ljLv3aFGVT3;zIhNjNEZtGD;zB4TAB8ePrV;fSCC7cdqGzp;WE10IzzxXry;sHVz8TSkrwf;px0mFynZu1Y;iqo7yTxTjYc;ckXHRGoSCrH;IuB58NfylWy;xpdmCteYBZL;yqC5qDpavqe;xt8YjoHmTjB;nIVeLcaNyba;X08rKHidXXX;poTDSqQ1eoG;b2TxNaUjUaP;ubB2YdRVO6J;LCo2wZO9FNk;Rxqg7LWPxtT;HFyxLiUrvVs;KrUiSi2PMFL;GShTZi0eIP7;PXEg4cCkTD8;pAtcpF6htZO;Ovf5eUvJWyH;vqzcMlZwauX;pBSIF2PXFU3;x6XAgb1n2ti;h1R68dlfd3r;GN1xfWLMYuZ;dnmw0RtsCEP;qkSuNHJnLPL;txsZCpIpWzg;b6JULkeYOde;kAFWQZOYjQC;E01v8P8WGNZ;LpRzsK8dDJB;WINRGUnoGty;aE3BTI0szrd;OZo06JtMIhY;Y1uydfRNkZM;BAEqtWpqxTP;iQQvVGSRxEs;qsX20M2B6Ux;p0z0Oal67DS;ZZL8Ovs3uAh;HZw6pGWIXzS;uKRPLp3EZrY;cGJI9K5Nw7v;bkVVjt9ipCW;uo9NAz5vc3m;a2n3SKxGMPb;qEQQHPvbZuQ;CvgJKRz1EhD;G7g5wp5ihje;VyGmb1B1WqU;GMbI9GIBPe6;CTOfrhby8pL;FTIIoKaNEUS;Tq5xPpIpD2P;gfmtm0tpHLW;Zzq1cqAAj36;C0caoP91AVK;JoiW4sOwAun;HzBypt3Nxvj;z6uW9leRCGk;Qeex7ygYxED;NUYMcH8Zc05;XPA4wQAREUx;tfGARI1qcyw;hadatRJ8eVK;Yrx5DrCGTMa;ZAlmDkNuylh;ItZ5Yxv5G3i;dFEufZ5xQBK;VrHT0o7hRm3;fh3qIB7F8mc;ip2u55l8gaW;cIofft82ABQ;A9OCT1zhvjH;G6pN02X1JNX;cwy3ZX0xhDh;k1ogu1DwP6A;gEqXANGGrGM;WpPGXswH4Iu;c87KevTn9YS;MFDMfUBhLTN;U2m9P0Z3XSG;bkjv0fLmfJM;u3CVZsBrZct;GHU2wsQMMXe;uNmQm86U687;sXAD0arxQLs;q4L1Fr4F0Un;wpRwzlPxoY5;DNhuheEjwax;w4HMUgc9lmp;eDVQpZXQ12Q;w4VFqBkCu67;ZZ4y9mcangW;tmMsTKp1urO;FmZu69GBy2E;aTXVTAdI4x9;jUWOCM14xBb;h3JGMKt2cJf;mQaSpaJaUQ2;FemLR1qpNdB;lwv1Ekk2SVA;pY3MLQazWpr;HxsDjAJM6k9;VO2e9LNx8cz;dD5lPC6ge6E;ThpCH25wncc;hzYrv8SEWVj;uw6H8GiWMV9;mezlxMZztNh;rAjF7tknpU6;H6mkpuB6ih9;QvUnqgsEx6c;wRhLx8dgU3z;jB9ATEMUAzp;ss78TKHm7WG;onUAlZmWFLf;y4WKdIOJfIy;j6qcfe7kHh2;GNIcBXvw85A;x9jQ1xWT41j;ikfWi2F5wvF;BQLnSAcIbbU;tJP27qp0Q66;FN3GOoBLiJ0;KO5KjWpDXMi;Qw5pJ5q5Akh;RDqfkJz7W1n;IDK8Wo2JGcO;MhRBio0OLDY;UGcAHzk77XK;RhKOVMYFrbT;SICusRcYKgm;GJkxyy3Z6gp;vESSJyUaLtH&displayProperty=NAME&outputIdScheme=CODE"), userpwd="UserName:Password", httpauth = 1L) |
||
45 | |||
46 | Intermediate <- read.table(text = Intermediate, sep =",", header = TRUE, stringsAsFactors = FALSE) |
||
47 | |||
48 | # head(Intermediate) |
||
49 | |||
50 | |||
51 | |||
52 | |||
53 | |||
54 | # For Susceptible ------ |
||
55 | |||
56 | Susceptible <- getURL(paste0("https://amr-host.zm.dhis2.site/ohs/api/29/analytics.csv?dimension=pe:LAST_3_MONTHS&dimension=ou:OU_GROUP-lvbz0mkIFZU;AWn3s2RqgAN;utIjliUdjp8;J7PQPWAeRUk;KozcEjeTyuD;B1u1bVtIA92;dbTLdTi7s8F;SwwuteU1Ajk;q5hODNmn021;oPLMrarKeEY;g1bv2xjtV0w&dimension=dx:w10DvjAoX5b;TXxhNIiRWG3;p7DKI2P8DhX;vAq0xfHyaDt;wtRG7uuFaB4;IQawXWSRZFy;czap5LIrHvt;j1OCvwnf2Er;qsr5ofdwOgC;eylCJ3gj3nA;hy7XUaWuRIV;kUia6DzmeFJ;NE1szb2KYfH;bKd9D3iAp58;AnA7OmTIC8c;PYc5G6n1JLL;c4FNZgtcOJq;Id4oqKXV5CI;Ty1TlWLMDLK;pVRBP6uNlpW;DA6dsII6AiP;dZgPuilm57X;ONZBDygpbNT;wfol48XS1PY;ULGsa8x4Qlr;grWHhriaiJg;Q3XWVb4BR4R;uCubjY5FyZ6;YcUP7doT4gK;CRcXr1694GJ;K0vimdA07vD;A49JgPIRxmD;yqcgL2OyBAD;kPxEN8V8Z29;fWM2kZhSiFO;yuVvIV7fB0o;cUjVbWil3gA;qB7mpfacjIU;LgITUDUkQX7;x1DHufnmKTs;KS1M8LS4muK;Hk78xE0lIrk;TMPHUevWLjX;HKSxrDgIKT7;WAM1Fs0xLsL;YnOdfZSwOKr;jCtnP7cYOaX;k4gUKT9kvCH;Jc0WaNlOxc9;cOVkf0FmB4m;ZBrMkOpcdny;Mczuf1kebf3;JlqTrUWImzW;odi5xXTiP9L;PW7TmgEOzfI;qC34bZWQRdJ;OMMJBXJ7pYa;Tjxgbk8rPjM;fQAz8Iv7wea;XGETAoqFw78;DrOIJdtufY2;dROYrYjnXRV;xmAIiaNfvXR;haW0MPgyNIb;ez87C6faFbi;wfZnu2da30Y;qGaUxNFnsz0;Qqk88yrl6Lf;VgELzsjLdSK;LsKUExesXVZ;pWWB4qN7e9S;PMwr5nuXjir;w4QI2DjORlk;UWJGnRrdN8j;XbwQByrHoCO;Gluj6UhubN3;wmyR2G9ESzS;Xvn0ElEO4ki;ty3XSu6Ppm0;RIiNeyJZX29;l38EX2Nm2a2;cb1dJRpQ8Rw;kYRc6Sq0Xbl;HOX7kcnVI79;hATddnQQMUS;pOfaUWBCVX7;UTEWHKXBFWF;KFIgSlACd6R;cZpKPLmsnHD;Ul7nKdSiXhj;DGoYXNwH5jz;esjYggc3aJS;gZkT7ukYV67;y26GCqR0h09;Y8KdBTl5KXa;tWT04TSUSgO;cnf2ynsuwAa;HAJqBQAMME9;amX3IgzO2pQ;wJsXVu0MVKI;od2qBd9xWGF;BZ42PHD4kov;Ck18GqpcxzJ;O1QafHB1NPe;Co3JU6cXapA;m3AUXJgbNSp;OSReFy9Jzkz;hf661KHlEN5;jWscaNhpicn;WdNoToiX1ci;r2zsOSIzSJX;vlxC8yBNBIA;ff20peq5QBg;IGS1ufQkFUH;udbfGPH7MoW;RupGJJdPkke;oZABAj5UgLi;Cwn8fAU6zWH;vgeKJq5xq5L;LU0N0RPB7oy;U06uZ1UaB4F;R30uLApE4bN;IpusnWEIbZH;FQmRbKrBKrt;EVCgxHSFBQf;I5yJTR5l0Ed;VW84KYAgrFj;pH6h60ULW8O;GopKOwl50Yn;bcd8HYyQSBp;BbfzQ3vlpgk;FKqw130og3t;BKdGdTGRPLX;fNuSbGryeEN;j2QdpLMjD34;KyCPNjQLxmS;z7QBlpuwKKe;DL6rirddhet;Q7MuMzjmGCE;TwjslaSpfU6;h1bnuAWhZBc;ZJA6SSwlZHR;URhXa8eUok7;YloyiP9yLI8;CIyxv21uXjJ;ir9xLQbdfmq;erUtSTtEdT5;F3nmrZvSUXO;WYKaq23JGps;eQAHVtJjmAJ;CJZO8sb9Xql;RXQ4jzI771L;zorjLbFuwBq;XjxW7LjyQKA;jI7GwBrejxC&displayProperty=NAME&outputIdScheme=CODE"), userpwd="UserName:Password", httpauth = 1L) |
||
57 | |||
58 | Susceptible <- read.table(text = Susceptible, sep =",", header = TRUE, stringsAsFactors = FALSE) |
||
59 | |||
60 | # head(Susceptible) |
||
61 | |||
62 | |||
63 | |||
64 | |||
65 | |||
66 | # For Not_tested |
||
67 | |||
68 | Not_tested <- getURL(paste0("https://amr-host.zm.dhis2.site/ohs/api/29/analytics.csv?dimension=pe:LAST_3_MONTHS&dimension=ou:OU_GROUP-lvbz0mkIFZU;Ot1P2HjvtvL&dimension=dx:nb3h2GxXoKa;uqOCZNOhbv5;ZMIqcVMsUgr;gxkchFhlReb;nW7I08Z8V91;EsaPkvtVWWa;em22fOVEV62;jwDfTKxRnxU;I3DL7vRaN6m;zmJ2vrtc8nC;oFBW8X4br7A;sB9NowuDaZr;kdXAYSrqTQ1;A995TFMy5XE;QGGycYsDb9i;lzokvvadU8t;vqu5JDao1Y1;iDVXqLTQaLi;qrGLCkURCuQ;xGTM2E3kMvt;Th1qEqGDWaW;jUgJhlQPGqj;Qfh7Rq0SCG6;qF1b8Jie35Y;GVlHFxzDqGu;YPjdRuUEdwK;cjIYkZ19GGi;ndYm1QLu7u9;czvwjrFVfuc;xbFe2DwVLEK;cT4r66gVNwy;JydtSoEvjqw;XvJiTMULujb;yMNogmQ6UXB;ACq7Q64vytf;PLMC0aF02LO;HEF12SNvgL9;DHuhuiKCPvE;vsKlNGrjzwv;nuPhFeCU5aV;Wv3M7ytxW8C;uLoRTxf68Rz;jaH1yUKgnfM;AbOkSE4cIVn;KLHG5ew6veL;grW3VDMLRbT;v6hNWCor7BM;ohPZTOACvHH;A8CADbDfAbe;kjcRbghCsMm;sZJfll3rFDx;Jrv2wzEAF6M;Mkg4LkvHPph;mBsEQN98yN8;HlU9uVPvBAw;BY5gZgKGmeS;AMIon8Q6mgD;PpVHRCeRLLl;oHAmHR6yofc;RpOjuigYAbv;GovQy8ky2Nl;I9A4IUHaB89;sF15kLzHHhK;urO7suYOqbK;ONqWN49Mf11;t0A6KwFrvkt;ONLlNrmHAiW;fCH4JznPrJc;xoQQcvCQaPa;Qd5ds8UdjW7;FqIOtcIclig;LiyLKcyVMz1;C3CMBQsTbvr;WWZHDnW63kF;fKgY0evZnmk;ygewzmLUCnA;MIULlGfrvyt;mBIUWijrMNR;FqZhtpLClKl;K59CcCd2dai;hOrr8lBFoPW;sYIAfO2fDVT;KskvTjPx7Iv;T3yMMp1toRo;VBZz3fvN5sn;uFDb4iiGxfp;vJIuTgb92cI;p8yALFjSgzn;nKMLTcTvmSS;AiIocdRAB4f;x3vFa0h3MdQ;FnCw7vGwhPK;RONKWYLR62n;qySM1eL0TPj;Kjszz3YyoTr;lwbriETvsxr;OizautezwKv;Y9MgMDjwlLR;wTJhMC93iNd;oOW0mL4JgUN;ir2YjUDKX2Q;F0YqBkIbMXc;TPCs1blb9cO;yRRHafMHMSQ;Bico5WsiyMf;z3xwUEg08Y9;z8plOBpLIjl;snpbY5mzfZD;MhcQE56MYi9;eoj9AxwqBaG;MOjhRlmQYPA;H70JDP3Y7tk;BndDjoeGQRx;vYNfZeq6J8G;Hx8CNHFW8KS;EnIPYeIlMkz;sI02Fp8QwIF;gGIcu6iqCL7;l9R5rgYaOhv;TkHIYTURSQs;xHI71NGhWCS;Z1nJbxttCmP;pEAISCVle7P;rJOIwWOGReb;HcQjezUcr3R;BfAJnD7KMIS;aBBsjaTPvGj;Ou7SCIMyfzw;bmdbr0m98RP;MwunTwLZIiR;ErusjL6v23Q;nTX8H5SD54Y;UFevOKYTLSN;qgAU2qNjQ1t;CyBgKUL2PcX;Pggaqn871Gg;kRDqk0FVrnK;dCCT7cK9a1b;pCCj1Zlka3b;Qq6A4ieuGkV;BWXSDmZSmwd;OR98ixTejrc;TVUHc21zgww;nxIYK1VF0U6;YPiFanzXOsc;u0T0lR8zxAy;mW5XrEFTspW;K37A10Y3ODh;kBHqXQrLITE;lGEIZeHCxg7;sYRiS83BTTB;kmN4MsaatB0;iSVBmMNk8zz;qx9VSSvz2DP;OIPXozD6gUJ&displayProperty=NAME&outputIdScheme=CODE"), userpwd="UserName:Password", httpauth = 1L) |
||
69 | |||
70 | Not_tested <- read.table(text = Not_tested, sep =",", header = TRUE, stringsAsFactors = FALSE) |
||
71 | |||
72 | # head(Not_tested) |
||
73 | |||
74 | |||
75 | |||
76 | # ========================== Blending the data categories and Processing for CSV format file ========================= |
||
77 | |||
78 | |||
79 | |||
80 | # To combine all dataframe into one frame. |
||
81 | |||
82 | RIS <- rbind(Resistance, Intermediate, Susceptible, Not_tested) |
||
83 | |||
84 | |||
85 | |||
86 | # To split Data into Data element and Category combination. |
||
87 | |||
88 | RIS <- RIS %>% separate(Data, c("Dataelement", "Category"), sep = "-", fill = 'right') |
||
89 | |||
90 | |||
91 | |||
92 | if (NROW(RIS) > 0){ |
||
93 | |||
94 | # Assign attribute into dataframe. |
||
95 | |||
96 | RIS$attr = '' |
||
97 | |||
98 | |||
99 | |||
100 | # Renaming |
||
101 | |||
102 | colnames(RIS)[4] <- "Org_unit" |
||
103 | |||
104 | |||
105 | |||
106 | # Rearrange for importing. |
||
107 | |||
108 | RIS <- RIS[, c(1,3,4,2,6,5)] |
||
109 | |||
110 | |||
111 | |||
112 | # miss <- RIS[is.na(RIS$Category), ] |
||
113 | |||
114 | # miss |
||
115 | |||
116 | # RIS |
||
117 | |||
118 | |||
119 | |||
120 | # File exporting |
||
121 | |||
122 | write.csv(RIS, '/home/DHIS2-Aggregate/AMR_data.csv', row.names = F, quote= T) |
||
123 | |||
124 | print('========== Successfully file exported ===========') |
||
125 | |||
126 | |||
127 | |||
128 | } else{ |
||
129 | |||
130 | |||
131 | |||
132 | print('========== No data found ==========') |
||
133 | |||
134 | } |
||
135 | |||
136 | |||
137 | </code></pre> |