From 34974b6a1ca7497a08aafe47a3b75ba845e486ab Mon Sep 17 00:00:00 2001 From: Lu Zhou Date: Wed, 17 Jul 2024 11:46:33 -0700 Subject: [PATCH 1/3] GML-1815 feedback anayltics tools --- copilot/docs/notebooks/FeedbackAnalysis.ipynb | 1727 +++++++++++++++++ 1 file changed, 1727 insertions(+) create mode 100644 copilot/docs/notebooks/FeedbackAnalysis.ipynb diff --git a/copilot/docs/notebooks/FeedbackAnalysis.ipynb b/copilot/docs/notebooks/FeedbackAnalysis.ipynb new file mode 100644 index 00000000..dc1c0bef --- /dev/null +++ b/copilot/docs/notebooks/FeedbackAnalysis.ipynb @@ -0,0 +1,1727 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Users:\n", + " - Name: tigergraph\n", + " - Global Roles: superuser\n", + " - LastSuccessLogin: Tue Jul 16 17:02:03 UTC 2024\n", + " - NextValidLogin: Tue Jul 16 17:02:03 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: parker.erickson@tigergraph.com\n", + " - Global Roles: superuser\n", + " - Secret: r35****ure\n", + " - Token: uln****ej2 expire at: 2024-07-26 20:32:50\n", + " - Alias: AUTO_GENERATED_ALIAS_8giecm5\n", + " - GraphName: Transaction_Fraud\n", + " - Secret: 82p****27t\n", + " - Token: 19a****pq0 expire at: 2024-07-25 13:16:27\n", + " - Alias: AUTO_GENERATED_ALIAS_mmmqfdo\n", + " - GraphName: MyGraph\n", + " - Secret: d19****3j3\n", + " - Token: jds****ho3 expire at: 2024-07-25 13:16:47\n", + " - Token: vnf****26n expire at: 2024-07-25 23:49:57\n", + " - Token: ueq****big expire at: 2024-07-25 13:16:47\n", + " - Token: vin****83a expire at: 2024-07-25 16:26:52\n", + " - Token: mg7****er9 expire at: 2024-07-27 17:17:29\n", + " - Token: iev****k0r expire at: 2024-08-11 15:30:04\n", + " - Token: lbh****5c9 expire at: 2024-07-26 13:07:42\n", + " - Token: diu****6nl expire at: 2024-07-25 16:13:47\n", + " - Alias: AUTO_GENERATED_ALIAS_3nd4ejm\n", + " - GraphName: pyTigerGraphRAG\n", + " - LastSuccessLogin: Wed May 08 13:01:28 UTC 2024\n", + " - NextValidLogin: Wed May 08 13:01:28 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: zhixian.yan@tigergraph.com\n", + " - Global Roles: superuser\n", + " - LastSuccessLogin: Wed May 08 13:03:23 UTC 2024\n", + " - NextValidLogin: Wed May 08 13:03:23 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: duc.hoai.le@tigergraph.com\n", + " - Global Roles: superuser\n", + " - Secret: mm6****03t\n", + " - Token: bo1****0on expire at: 2024-07-17 20:07:07\n", + " - Token: b4d****omu expire at: 2024-07-17 20:48:13\n", + " - Token: r05****b22 expire at: 2024-07-19 00:01:03\n", + " - Token: g22****tpm expire at: 2024-07-17 20:47:33\n", + " - Token: t4n****va8 expire at: 2024-08-11 01:31:20\n", + " - Alias: AUTO_GENERATED_ALIAS_gioopv6\n", + " - GraphName: MyGraph\n", + " - LastSuccessLogin: Wed May 08 13:03:23 UTC 2024\n", + " - NextValidLogin: Wed May 08 13:03:23 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: douglas.garrigan@tigergraph.com\n", + " - Global Roles: superuser\n", + " - Secret: p1g****acg\n", + " - Token: g7v****01g expire at: 2024-07-19 23:11:06\n", + " - Token: blk****0c6 expire at: 2024-07-20 01:07:53\n", + " - Token: hi8****974 expire at: 2024-07-28 17:50:41\n", + " - Token: oiu****6i8 expire at: 2024-07-27 20:29:21\n", + " - Token: pkq****igc expire at: 2024-07-25 03:00:31\n", + " - Token: 9sr****ln4 expire at: 2024-07-27 20:27:33\n", + " - Token: o2t****61m expire at: 2024-07-25 03:02:48\n", + " - Token: 0a1****b3i expire at: 2024-07-21 02:37:52\n", + " - Alias: AUTO_GENERATED_ALIAS_fa9hmth\n", + " - GraphName: Transaction_Fraud\n", + " - Secret: sjl****245\n", + " - Token: rp0****qfc expire at: 2024-07-27 20:27:30\n", + " - Token: 8dr****o3b expire at: 2024-07-19 23:08:49\n", + " - Token: tsc****kh0 expire at: 2024-07-20 01:05:17\n", + " - Token: imq****g28 expire at: 2024-07-25 03:00:07\n", + " - Token: 5i6****e5t expire at: 2024-07-23 10:56:05\n", + " - Token: a5k****ms6 expire at: 2024-07-28 17:50:09\n", + " - Alias: AUTO_GENERATED_ALIAS_2jgiecd\n", + " - GraphName: MyGraph\n", + " - Secret: q6u****9mm\n", + " - Token: eni****5cb expire at: 2024-07-28 17:51:23\n", + " - Alias: AUTO_GENERATED_ALIAS_n6coqt4\n", + " - GraphName: pyTigerGraphRAG\n", + " - LastSuccessLogin: Wed May 08 13:03:24 UTC 2024\n", + " - NextValidLogin: Wed May 08 13:03:24 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: wyatt.joyner@tigergraph.com\n", + " - Global Roles: superuser\n", + " - LastSuccessLogin: Wed May 08 13:03:24 UTC 2024\n", + " - NextValidLogin: Wed May 08 13:03:24 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: carl.boudreau@tigergraph.com\n", + " - Global Roles: superuser\n", + " - LastSuccessLogin: Wed May 08 13:03:25 UTC 2024\n", + " - NextValidLogin: Wed May 08 13:03:25 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: alexander.thomas@tigergraph.com\n", + " - Global Roles: superuser\n", + " - LastSuccessLogin: Wed May 08 13:03:26 UTC 2024\n", + " - NextValidLogin: Wed May 08 13:03:26 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: robert.rossmiller@tigergraph.com\n", + " - Global Roles: superuser\n", + " - Secret: 819****0nu\n", + " - Alias: AUTO_GENERATED_ALIAS_poimof6\n", + " - GraphName: Transaction_Fraud\n", + " - Secret: o7k****ulg\n", + " - Token: 70t****45s expire at: 2024-07-26 16:41:47\n", + " - Token: cmq****4o3 expire at: 2024-07-25 21:46:37\n", + " - Token: n81****4b0 expire at: 2024-07-25 21:46:38\n", + " - Token: 36d****6qt expire at: 2024-07-26 16:41:48\n", + " - Alias: AUTO_GENERATED_ALIAS_n7kg136\n", + " - GraphName: TigerGraphRAG\n", + " - Secret: qoh****0os\n", + " - Token: v36****d5i expire at: 2024-07-24 17:44:46\n", + " - Token: a1m****h9n expire at: 2024-07-24 23:42:02\n", + " - Token: 0it****lfi expire at: 2024-07-17 15:10:42\n", + " - Token: 4t6****48s expire at: 2024-07-20 18:53:26\n", + " - Alias: AUTO_GENERATED_ALIAS_j0frhbm\n", + " - GraphName: MyGraph\n", + " - Secret: m5o****bar\n", + " - Token: l82****bur expire at: 2024-07-25 16:23:42\n", + " - Token: eal****rsc expire at: 2024-07-25 16:07:44\n", + " - Token: mgk****pao expire at: 2024-07-25 16:07:44\n", + " - Token: h77****h1r expire at: 2024-07-25 16:23:43\n", + " - Token: 9s0****5ec expire at: 2024-07-25 13:05:55\n", + " - Token: 0oo****npr expire at: 2024-07-25 13:05:56\n", + " - Alias: AUTO_GENERATED_ALIAS_p6kkmmo\n", + " - GraphName: pyTigerGraphRAG\n", + " - LastSuccessLogin: Wed May 08 13:03:26 UTC 2024\n", + " - NextValidLogin: Wed May 08 13:03:26 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: bill.shi@tigergraph.com\n", + " - Global Roles: superuser\n", + " - Secret: dak****n4k\n", + " - Alias: AUTO_GENERATED_ALIAS_164iqak\n", + " - GraphName: Transaction_Fraud\n", + " - Secret: 1tl****une\n", + " - Token: s7h****ql1 expire at: 2024-07-24 16:44:33\n", + " - Token: kup****8t9 expire at: 2024-07-24 01:02:03\n", + " - Token: jav****14h expire at: 2024-07-24 04:29:53\n", + " - Token: c3v****h41 expire at: 2024-08-09 17:36:49\n", + " - Token: ils****qfq expire at: 2024-07-25 22:07:34\n", + " - Alias: AUTO_GENERATED_ALIAS_uift7s8\n", + " - GraphName: MyGraph\n", + " - Secret: cio****1rm\n", + " - Token: aid****993 expire at: 2024-08-09 17:36:52\n", + " - Alias: AUTO_GENERATED_ALIAS_2e5g1jb\n", + " - GraphName: pyTigerGraphRAG\n", + " - LastSuccessLogin: Wed May 08 13:03:27 UTC 2024\n", + " - NextValidLogin: Wed May 08 13:03:27 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: yuling.liu@tigergraph.com\n", + " - Global Roles: superuser\n", + " - LastSuccessLogin: Wed May 08 13:03:28 UTC 2024\n", + " - NextValidLogin: Wed May 08 13:03:28 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: kevin.stone@tigergraph.com\n", + " - Global Roles: superuser\n", + " - LastSuccessLogin: Wed May 08 13:03:28 UTC 2024\n", + " - NextValidLogin: Wed May 08 13:03:28 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + "* - Name: supportai\n", + " - Global Roles: superuser\n", + " - Secret: gj6****erl\n", + " - Token: kbi****5vk expire at: 2024-07-26 14:37:39\n", + " - Token: 2a8****geq expire at: 2024-07-27 20:51:15\n", + " - Token: i9j****4lq expire at: 2024-07-25 20:41:12\n", + " - Token: emc****gmi expire at: 2024-07-28 15:12:52\n", + " - Token: tq6****is5 expire at: 2024-07-26 21:35:52\n", + " - Token: i3k****2pi expire at: 2024-07-25 20:06:54\n", + " - Token: 0nr****un6 expire at: 2024-07-26 21:48:36\n", + " - Token: lt9****4lv expire at: 2024-07-28 11:04:42\n", + " - Token: 7f7****j5g expire at: 2024-07-24 18:58:16\n", + " - Token: db2****aho expire at: 2024-07-27 20:29:54\n", + " - Token: t6r****5js expire at: 2024-07-25 20:32:16\n", + " - Token: a3s****94s expire at: 2024-07-26 20:00:56\n", + " - Token: v77****cfd expire at: 2024-07-25 21:24:57\n", + " - Token: he0****cdm expire at: 2024-08-11 18:30:53\n", + " - Token: 8v3****03q expire at: 2024-07-21 16:45:22\n", + " - Token: 8pj****73j expire at: 2024-07-26 00:13:31\n", + " - Token: nro****5fv expire at: 2024-07-25 21:24:41\n", + " - Token: vnu****ptn expire at: 2024-08-03 11:00:45\n", + " - Token: n2e****p8b expire at: 2024-08-07 19:16:40\n", + " - Token: uk7****1tn expire at: 2024-07-26 19:27:55\n", + " - Token: 4cn****ik8 expire at: 2024-07-25 20:54:56\n", + " - Token: o66****qdt expire at: 2024-07-26 19:09:04\n", + " - Token: j2s****d5o expire at: 2024-07-28 17:03:35\n", + " - Token: mqm****r1l expire at: 2024-07-26 00:07:37\n", + " - Token: pge****hig expire at: 2024-08-04 16:17:36\n", + " - Token: 0qa****qr6 expire at: 2024-07-25 03:52:04\n", + " - Token: dvd****4fg expire at: 2024-07-25 22:27:32\n", + " - Token: ve0****1vb expire at: 2024-07-25 20:58:27\n", + " - Token: f0q****7bs expire at: 2024-07-27 18:13:18\n", + " - Token: gom****2c9 expire at: 2024-07-21 08:12:01\n", + " - Token: kd8****7ie expire at: 2024-08-02 15:58:20\n", + " - Token: ar5****gbp expire at: 2024-08-04 16:16:32\n", + " - Token: lkc****drk expire at: 2024-07-26 19:00:54\n", + " - Token: akt****cch expire at: 2024-07-26 20:42:25\n", + " - Token: 35f****6pe expire at: 2024-07-25 22:53:37\n", + " - Token: a22****5sj expire at: 2024-07-25 20:49:06\n", + " - Token: hec****bkc expire at: 2024-07-25 23:00:06\n", + " - Token: o84****d8k expire at: 2024-07-27 20:50:07\n", + " - Token: 74i****1e2 expire at: 2024-07-21 08:03:17\n", + " - Token: ask****83l expire at: 2024-07-25 19:56:46\n", + " - Token: 786****eg6 expire at: 2024-07-26 04:55:53\n", + " - Token: s8a****cio expire at: 2024-08-03 15:49:25\n", + " - Token: 506****ua6 expire at: 2024-07-28 13:51:54\n", + " - Token: 973****ggo expire at: 2024-07-28 15:51:59\n", + " - Token: 831****925 expire at: 2024-07-26 20:08:09\n", + " - Token: 335****sm4 expire at: 2024-07-21 07:29:52\n", + " - Token: klp****b0u expire at: 2024-07-25 22:15:55\n", + " - Token: j18****97v expire at: 2024-07-26 03:29:46\n", + " - Token: 2er****i5q expire at: 2024-08-11 02:13:42\n", + " - Token: j79****irv expire at: 2024-07-28 15:38:49\n", + " - Token: lg2****h6k expire at: 2024-07-26 14:07:09\n", + " - Token: vqr****96m expire at: 2024-07-25 20:11:13\n", + " - Token: 5tg****cne expire at: 2024-07-31 16:45:19\n", + " - Token: 218****l8f expire at: 2024-07-25 21:47:41\n", + " - Token: 5g9****103 expire at: 2024-07-26 21:34:46\n", + " - Token: ak5****8t9 expire at: 2024-07-26 21:34:12\n", + " - Token: 6fg****5pt expire at: 2024-07-26 03:53:05\n", + " - Token: tn7****nmm expire at: 2024-07-26 04:39:38\n", + " - Token: 2f3****aam expire at: 2024-07-25 19:24:09\n", + " - Token: tmn****icm expire at: 2024-08-11 19:37:31\n", + " - Token: fll****t3o expire at: 2024-07-26 20:26:46\n", + " - Token: i33****0o7 expire at: 2024-07-26 00:13:34\n", + " - Token: 399****qcr expire at: 2024-07-25 22:38:13\n", + " - Token: mi6****ljc expire at: 2024-07-24 20:53:36\n", + " - Token: ve9****eco expire at: 2024-07-28 14:58:07\n", + " - Token: t3n****tgs expire at: 2024-07-26 18:59:36\n", + " - Token: 129****rnc expire at: 2024-07-27 20:56:21\n", + " - Token: cqb****beq expire at: 2024-08-04 17:51:07\n", + " - Token: k1a****ds2 expire at: 2024-08-11 15:17:15\n", + " - Token: 22l****fgv expire at: 2024-08-03 19:16:23\n", + " - Token: uov****soo expire at: 2024-07-25 19:16:17\n", + " - Token: lm3****oat expire at: 2024-07-26 14:06:43\n", + " - Token: fgu****m4f expire at: 2024-07-25 22:45:49\n", + " - Token: les****l50 expire at: 2024-07-25 21:56:54\n", + " - Token: u80****eih expire at: 2024-07-25 19:47:36\n", + " - Token: vit****s6g expire at: 2024-07-21 07:23:57\n", + " - Token: qsh****dgh expire at: 2024-07-25 20:51:58\n", + " - Token: her****o73 expire at: 2024-07-25 20:48:59\n", + " - Token: stq****0cu expire at: 2024-07-26 21:02:00\n", + " - Token: js9****g76 expire at: 2024-07-27 20:29:49\n", + " - Token: fp5****0po expire at: 2024-07-21 08:13:13\n", + " - Token: ns6****r77 expire at: 2024-07-28 13:34:25\n", + " - Token: eo5****uq6 expire at: 2024-08-03 17:52:17\n", + " - Token: 7d6****sdv expire at: 2024-07-24 18:58:58\n", + " - Token: 2pa****dnj expire at: 2024-07-26 21:45:42\n", + " - Token: 95u****k2a expire at: 2024-07-27 22:38:41\n", + " - Token: 69g****ncs expire at: 2024-07-21 08:07:51\n", + " - Token: hj4****ntj expire at: 2024-07-27 22:41:42\n", + " - Token: hiq****5v4 expire at: 2024-07-21 08:14:24\n", + " - Token: 3po****fd9 expire at: 2024-07-26 13:43:29\n", + " - Token: b09****bm1 expire at: 2024-07-25 21:26:54\n", + " - Token: 6of****kfs expire at: 2024-08-11 02:18:26\n", + " - Token: n3e****cnn expire at: 2024-07-27 20:32:38\n", + " - Token: po8****ioj expire at: 2024-07-27 20:50:52\n", + " - Token: 1fk****7jb expire at: 2024-08-11 21:04:16\n", + " - Token: ft8****s3d expire at: 2024-07-25 21:11:54\n", + " - Token: pq0****a7g expire at: 2024-07-27 20:50:31\n", + " - Token: 50p****lpu expire at: 2024-07-28 14:47:40\n", + " - Token: oan****da9 expire at: 2024-08-04 15:15:26\n", + " - Token: 622****95g expire at: 2024-07-26 21:48:06\n", + " - Token: 4ga****kje expire at: 2024-07-25 20:49:29\n", + " - Token: brc****v9s expire at: 2024-07-26 00:08:15\n", + " - Token: mu4****v7q expire at: 2024-07-27 20:33:49\n", + " - Token: n3q****ubo expire at: 2024-07-26 20:41:27\n", + " - Token: 1u5****lbq expire at: 2024-07-26 21:36:06\n", + " - Token: cup****cv0 expire at: 2024-07-25 22:54:09\n", + " - Token: 6hu****bvh expire at: 2024-07-25 21:21:36\n", + " - Token: ah7****o2n expire at: 2024-08-02 23:26:12\n", + " - Token: ip2****n5r expire at: 2024-07-25 19:00:02\n", + " - Token: 1dk****djm expire at: 2024-07-31 23:40:20\n", + " - Token: rli****t3m expire at: 2024-07-25 20:10:09\n", + " - Token: m7t****v4r expire at: 2024-07-28 17:18:03\n", + " - Token: ebp****p7j expire at: 2024-07-25 22:13:30\n", + " - Token: 9bt****686 expire at: 2024-07-27 23:05:50\n", + " - Token: u1i****8o1 expire at: 2024-07-28 18:34:12\n", + " - Token: r3r****pb0 expire at: 2024-07-26 03:43:31\n", + " - Token: uug****i4n expire at: 2024-08-11 15:18:18\n", + " - Token: br6****c8t expire at: 2024-07-24 20:54:50\n", + " - Token: k66****rer expire at: 2024-07-26 19:16:58\n", + " - Token: 765****mg8 expire at: 2024-07-25 21:26:41\n", + " - Token: mh8****lvh expire at: 2024-07-26 21:35:13\n", + " - Token: 1c2****16e expire at: 2024-07-26 14:33:05\n", + " - Token: frg****d84 expire at: 2024-07-25 19:38:31\n", + " - Token: ddr****5s0 expire at: 2024-07-26 00:07:48\n", + " - Token: fab****104 expire at: 2024-07-25 21:18:45\n", + " - Token: ovj****r8f expire at: 2024-07-25 22:30:59\n", + " - Token: ujc****s74 expire at: 2024-07-28 15:53:06\n", + " - Token: beo****tlc expire at: 2024-07-26 14:33:46\n", + " - Token: 48e****l3v expire at: 2024-07-31 17:49:58\n", + " - Token: ukp****5bd expire at: 2024-07-21 15:59:05\n", + " - Token: n8h****pag expire at: 2024-07-26 00:29:47\n", + " - Token: a9p****bc0 expire at: 2024-07-24 20:59:53\n", + " - Token: rbn****1ul expire at: 2024-07-28 18:10:16\n", + " - Token: 7cq****jif expire at: 2024-07-26 04:35:24\n", + " - Token: iul****h6i expire at: 2024-07-25 20:59:47\n", + " - Token: sb1****q5u expire at: 2024-08-03 19:32:22\n", + " - Token: n6t****eu6 expire at: 2024-07-25 21:42:30\n", + " - Token: 7mb****g6h expire at: 2024-07-26 13:34:31\n", + " - Token: t9s****thq expire at: 2024-07-25 20:22:28\n", + " - Token: c59****l4i expire at: 2024-07-26 04:52:22\n", + " - Token: 6j5****coe expire at: 2024-07-25 20:41:50\n", + " - Token: kth****o81 expire at: 2024-07-25 20:41:40\n", + " - Token: fse****rd1 expire at: 2024-07-25 22:07:03\n", + " - Token: oq0****a5q expire at: 2024-07-21 16:49:17\n", + " - Token: bmm****08m expire at: 2024-07-28 15:51:35\n", + " - Token: u0l****u1b expire at: 2024-07-21 07:03:19\n", + " - Token: rl2****i2b expire at: 2024-07-27 18:12:10\n", + " - Token: a5l****df6 expire at: 2024-07-24 18:48:41\n", + " - Token: 5t9****qfd expire at: 2024-07-24 23:12:44\n", + " - Token: 73e****7ve expire at: 2024-07-26 13:43:08\n", + " - Token: 33o****q82 expire at: 2024-07-25 20:17:13\n", + " - Token: 9i0****d7c expire at: 2024-07-26 20:41:31\n", + " - Token: 3nm****9aq expire at: 2024-07-26 00:03:11\n", + " - Token: sim****kfk expire at: 2024-07-25 17:44:47\n", + " - Token: 5po****ci7 expire at: 2024-07-28 15:46:47\n", + " - Token: u07****r4q expire at: 2024-07-25 22:13:55\n", + " - Token: 27g****jdp expire at: 2024-07-26 21:02:38\n", + " - Token: ok4****lqh expire at: 2024-08-03 17:28:26\n", + " - Token: ec9****kol expire at: 2024-08-11 18:49:25\n", + " - Token: vr0****1ud expire at: 2024-07-25 19:00:48\n", + " - Token: e1r****cin expire at: 2024-07-26 19:18:35\n", + " - Token: cm9****5da expire at: 2024-07-21 17:24:05\n", + " - Token: vr3****spq expire at: 2024-07-25 20:54:42\n", + " - Token: qe3****9uv expire at: 2024-07-25 20:09:40\n", + " - Token: pii****bfe expire at: 2024-07-25 17:43:45\n", + " - Token: 61c****fvu expire at: 2024-07-26 21:45:37\n", + " - Token: mqd****r9e expire at: 2024-07-25 20:44:53\n", + " - Token: enp****h8j expire at: 2024-08-10 20:48:59\n", + " - Token: fjv****4nv expire at: 2024-07-25 19:08:51\n", + " - Token: vor****2ki expire at: 2024-07-27 23:58:38\n", + " - Token: 6lb****4as expire at: 2024-07-26 00:08:36\n", + " - Token: q90****eu8 expire at: 2024-07-26 21:46:46\n", + " - Token: bil****sso expire at: 2024-08-03 11:00:43\n", + " - Token: nhf****hvr expire at: 2024-07-25 18:58:30\n", + " - Token: 486****1ei expire at: 2024-07-26 04:28:07\n", + " - Token: 73k****24i expire at: 2024-08-04 16:26:45\n", + " - Token: m5r****okj expire at: 2024-07-28 15:46:08\n", + " - Token: 70q****4dc expire at: 2024-07-21 08:06:42\n", + " - Token: i4e****k99 expire at: 2024-07-31 17:33:59\n", + " - Token: ku6****919 expire at: 2024-07-26 04:43:28\n", + " - Token: bce****hqk expire at: 2024-07-27 20:29:53\n", + " - Token: t51****t8l expire at: 2024-07-28 17:20:25\n", + " - Token: 5ao****6rr expire at: 2024-07-25 22:13:46\n", + " - Token: ukd****1rm expire at: 2024-07-21 16:43:56\n", + " - Token: v42****n1s expire at: 2024-07-26 16:18:32\n", + " - Token: g25****8ja expire at: 2024-07-26 20:24:35\n", + " - Token: ns2****sct expire at: 2024-08-11 01:19:12\n", + " - Token: adn****2bm expire at: 2024-07-25 20:10:37\n", + " - Token: pop****kic expire at: 2024-07-31 17:15:16\n", + " - Token: fvn****hm2 expire at: 2024-07-25 20:41:18\n", + " - Token: n1k****f3c expire at: 2024-07-26 17:18:42\n", + " - Token: ls7****m7f expire at: 2024-07-26 16:48:30\n", + " - Token: 79k****8bl expire at: 2024-07-26 20:54:48\n", + " - Token: 0mm****g6j expire at: 2024-07-31 23:51:19\n", + " - Token: 5hb****bo8 expire at: 2024-07-28 17:09:23\n", + " - Token: rcr****5vf expire at: 2024-07-26 20:21:14\n", + " - Token: 354****p55 expire at: 2024-07-25 21:26:00\n", + " - Token: 0nf****k3v expire at: 2024-07-21 14:54:03\n", + " - Token: 9jj****bho expire at: 2024-07-26 21:02:25\n", + " - Token: i5k****d9a expire at: 2024-07-31 17:17:18\n", + " - Token: u4e****90m expire at: 2024-08-03 15:44:59\n", + " - Token: p8n****r9s expire at: 2024-07-26 19:44:26\n", + " - Token: v13****m0d expire at: 2024-07-28 11:20:50\n", + " - Token: s66****mj4 expire at: 2024-08-04 15:36:37\n", + " - Token: pi5****19s expire at: 2024-07-26 03:26:03\n", + " - Token: c5a****1il expire at: 2024-07-28 14:07:24\n", + " - Token: u0q****1mb expire at: 2024-07-27 23:44:00\n", + " - Token: n2s****rfe expire at: 2024-07-28 11:23:06\n", + " - Token: 96c****ec2 expire at: 2024-08-11 02:39:54\n", + " - Token: 6h2****9tq expire at: 2024-07-27 18:12:32\n", + " - Token: ss1****tr7 expire at: 2024-07-25 19:30:12\n", + " - Token: gum****7sv expire at: 2024-07-25 19:33:37\n", + " - Token: 9bd****gk5 expire at: 2024-08-02 19:12:15\n", + " - Token: 73k****ca1 expire at: 2024-07-25 20:33:08\n", + " - Token: as9****p2l expire at: 2024-07-26 00:35:15\n", + " - Token: k1t****nij expire at: 2024-07-25 19:52:55\n", + " - Token: tna****6vj expire at: 2024-07-21 08:05:29\n", + " - Token: bce****fi0 expire at: 2024-07-26 04:24:24\n", + " - Token: tp8****c3a expire at: 2024-07-25 20:11:22\n", + " - Token: h83****9fc expire at: 2024-08-03 17:35:13\n", + " - Token: 807****5kd expire at: 2024-07-25 21:57:12\n", + " - Token: lbk****l1u expire at: 2024-08-10 22:03:48\n", + " - Token: ea9****2ji expire at: 2024-07-20 18:36:54\n", + " - Token: 8fp****moj expire at: 2024-08-11 13:48:47\n", + " - Token: k44****t2s expire at: 2024-07-27 23:19:49\n", + " - Token: qe2****mbl expire at: 2024-07-25 22:14:07\n", + " - Token: kjt****fmf expire at: 2024-07-26 00:06:49\n", + " - Token: en5****pd7 expire at: 2024-07-27 17:59:18\n", + " - Token: e9c****jum expire at: 2024-07-26 20:30:45\n", + " - Token: 10n****068 expire at: 2024-08-03 16:27:41\n", + " - Token: tbb****60q expire at: 2024-08-10 17:12:50\n", + " - Token: uva****aib expire at: 2024-07-27 22:30:45\n", + " - Token: 1vc****nrn expire at: 2024-08-04 16:15:29\n", + " - Token: 0u6****0r3 expire at: 2024-07-25 20:39:36\n", + " - Token: mgd****4k1 expire at: 2024-08-11 03:04:42\n", + " - Token: 7fr****nkq expire at: 2024-07-27 20:49:55\n", + " - Token: 5vo****gaf expire at: 2024-07-26 20:35:44\n", + " - Token: q1p****fpo expire at: 2024-07-26 19:44:29\n", + " - Token: ll3****qrt expire at: 2024-07-25 23:23:46\n", + " - Token: dj5****3j4 expire at: 2024-07-27 18:12:58\n", + " - Token: umr****17s expire at: 2024-07-27 20:51:42\n", + " - Token: ca8****pfe expire at: 2024-07-25 22:50:24\n", + " - Token: es1****orh expire at: 2024-07-26 18:59:51\n", + " - Token: nqf****qkp expire at: 2024-08-11 03:48:22\n", + " - Token: 0jq****dso expire at: 2024-07-26 05:22:21\n", + " - Token: mn5****ff6 expire at: 2024-08-11 02:54:50\n", + " - Token: 25p****kcv expire at: 2024-07-26 05:15:13\n", + " - Token: r4i****clo expire at: 2024-07-25 21:56:36\n", + " - Token: 010****1ci expire at: 2024-07-27 21:01:14\n", + " - Token: 46m****44d expire at: 2024-07-28 18:34:09\n", + " - Token: qj2****ec3 expire at: 2024-07-25 20:05:59\n", + " - Token: m65****erc expire at: 2024-07-25 21:12:11\n", + " - Token: e80****ek3 expire at: 2024-07-26 20:41:33\n", + " - Token: ifn****k7u expire at: 2024-07-28 10:57:10\n", + " - Token: bsr****5ob expire at: 2024-07-26 05:32:31\n", + " - Token: t8k****514 expire at: 2024-07-27 20:49:58\n", + " - Token: te4****inb expire at: 2024-07-21 16:29:55\n", + " - Token: hm6****971 expire at: 2024-08-11 14:22:18\n", + " - Token: vv4****f25 expire at: 2024-07-28 15:43:14\n", + " - Token: 5qr****i08 expire at: 2024-07-25 21:01:47\n", + " - Token: h9g****rfu expire at: 2024-07-25 21:56:59\n", + " - Token: 8bd****2bn expire at: 2024-07-26 21:35:26\n", + " - Token: v3u****t66 expire at: 2024-07-21 08:04:21\n", + " - Token: ec5****htp expire at: 2024-07-27 20:31:08\n", + " - Token: 4e3****173 expire at: 2024-07-28 13:44:01\n", + " - Token: ohr****iou expire at: 2024-08-12 05:44:48\n", + " - Token: de1****kp2 expire at: 2024-07-25 22:49:16\n", + " - Token: 8qv****amj expire at: 2024-07-25 02:29:34\n", + " - Token: 3te****k2t expire at: 2024-07-25 21:02:29\n", + " - Token: f0i****bql expire at: 2024-07-25 21:25:30\n", + " - Token: 76m****qji expire at: 2024-07-27 11:10:04\n", + " - Token: a4o****htr expire at: 2024-07-25 21:03:33\n", + " - Token: 716****bfg expire at: 2024-07-26 19:08:53\n", + " - Token: uuj****24b expire at: 2024-07-26 14:34:15\n", + " - Token: nkc****uti expire at: 2024-07-27 20:34:06\n", + " - Token: q4p****05g expire at: 2024-07-25 21:19:03\n", + " - Token: e13****260 expire at: 2024-07-25 20:18:06\n", + " - Token: ul9****msd expire at: 2024-08-03 11:06:29\n", + " - Token: f9f****tu4 expire at: 2024-07-25 20:09:58\n", + " - Token: bqn****076 expire at: 2024-07-26 00:07:02\n", + " - Token: aif****374 expire at: 2024-07-26 21:46:29\n", + " - Token: avf****att expire at: 2024-07-27 22:53:21\n", + " - Token: d5v****ai4 expire at: 2024-07-25 23:28:26\n", + " - Token: 0lu****b0j expire at: 2024-07-21 17:25:06\n", + " - Token: fqk****5bj expire at: 2024-07-25 22:16:09\n", + " - Token: abr****h3s expire at: 2024-07-21 08:02:24\n", + " - Token: ba3****q76 expire at: 2024-07-28 15:53:11\n", + " - Token: 28f****qat expire at: 2024-08-04 15:24:11\n", + " - Token: fco****769 expire at: 2024-07-25 19:48:26\n", + " - Token: pr5****4jb expire at: 2024-07-25 21:14:13\n", + " - Token: 3kh****92v expire at: 2024-07-26 19:21:36\n", + " - Token: hju****3pt expire at: 2024-07-28 17:17:42\n", + " - Token: 26i****gte expire at: 2024-07-25 18:19:16\n", + " - Token: d41****8b9 expire at: 2024-08-10 17:13:27\n", + " - Token: u57****uaa expire at: 2024-07-26 21:03:55\n", + " - Token: ld1****025 expire at: 2024-07-27 20:33:25\n", + " - Token: rmh****hjb expire at: 2024-07-31 23:28:08\n", + " - Token: 4co****o9f expire at: 2024-07-25 19:50:18\n", + " - Token: gs8****6al expire at: 2024-07-25 20:42:07\n", + " - Token: d2i****j9v expire at: 2024-07-21 16:31:26\n", + " - Token: 65h****d0p expire at: 2024-07-21 16:41:17\n", + " - Token: 0hd****qh7 expire at: 2024-08-11 15:36:49\n", + " - Token: vq2****rk9 expire at: 2024-07-25 20:02:06\n", + " - Token: nq2****0o2 expire at: 2024-07-26 14:34:03\n", + " - Token: 7jv****aak expire at: 2024-08-03 11:08:29\n", + " - Token: gag****qt1 expire at: 2024-07-28 13:54:04\n", + " - Token: g57****o24 expire at: 2024-07-21 16:43:12\n", + " - Token: mq8****fc3 expire at: 2024-07-28 15:49:59\n", + " - Token: 0t0****3t1 expire at: 2024-08-03 16:13:20\n", + " - Token: cvu****g01 expire at: 2024-07-25 20:55:13\n", + " - Token: 7s6****u9r expire at: 2024-07-25 17:46:03\n", + " - Token: 3lp****ium expire at: 2024-07-26 14:29:51\n", + " - Token: fkj****3gh expire at: 2024-07-26 20:30:59\n", + " - Token: imj****0lp expire at: 2024-07-25 23:10:20\n", + " - Token: d2c****9c0 expire at: 2024-07-26 20:53:22\n", + " - Token: igs****v9c expire at: 2024-08-04 16:05:57\n", + " - Token: rdp****332 expire at: 2024-07-25 20:45:59\n", + " - Token: 47u****bmk expire at: 2024-07-25 20:57:48\n", + " - Token: 95f****l13 expire at: 2024-07-25 23:36:25\n", + " - Token: 48e****r1r expire at: 2024-07-21 16:41:42\n", + " - Token: r3t****4qn expire at: 2024-07-27 20:51:59\n", + " - Token: fab****i0o expire at: 2024-07-28 17:18:05\n", + " - Token: g2m****fq7 expire at: 2024-07-26 00:28:10\n", + " - Token: aqo****c79 expire at: 2024-07-27 20:32:56\n", + " - Token: 0k5****bcc expire at: 2024-07-25 23:33:05\n", + " - Token: 84p****9au expire at: 2024-07-26 20:29:35\n", + " - Token: o2p****p9r expire at: 2024-07-25 23:38:23\n", + " - Token: ppm****g5a expire at: 2024-08-11 15:17:40\n", + " - Token: 5gp****9j0 expire at: 2024-07-26 21:24:49\n", + " - Token: 2fi****5n4 expire at: 2024-07-25 21:24:25\n", + " - Token: 3s9****hct expire at: 2024-07-26 20:42:08\n", + " - Token: 17e****etj expire at: 2024-07-27 22:50:34\n", + " - Token: ahf****39t expire at: 2024-07-25 20:18:57\n", + " - Token: uv3****f13 expire at: 2024-07-26 21:04:11\n", + " - Token: mem****b44 expire at: 2024-07-26 05:20:09\n", + " - Token: a55****hgj expire at: 2024-07-25 19:56:43\n", + " - Token: iba****7gh expire at: 2024-08-11 18:43:40\n", + " - Token: 09h****eb5 expire at: 2024-08-11 16:02:13\n", + " - Token: keq****7n0 expire at: 2024-07-28 18:18:18\n", + " - Token: 5cu****3in expire at: 2024-07-25 20:27:51\n", + " - Token: cr3****mn7 expire at: 2024-07-25 19:53:07\n", + " - Token: 5od****442 expire at: 2024-07-26 03:49:18\n", + " - Token: 32h****bo7 expire at: 2024-07-26 20:30:23\n", + " - Token: f6q****moo expire at: 2024-07-31 23:20:50\n", + " - Token: ndl****pma expire at: 2024-07-28 10:54:24\n", + " - Token: tsb****1tf expire at: 2024-07-26 00:03:15\n", + " - Token: net****9i1 expire at: 2024-08-03 19:53:36\n", + " - Token: 293****71o expire at: 2024-07-25 21:12:15\n", + " - Token: dpo****672 expire at: 2024-08-10 22:01:43\n", + " - Token: 7h4****g5d expire at: 2024-07-26 21:47:52\n", + " - Token: j89****g7s expire at: 2024-08-11 02:50:27\n", + " - Token: nt0****vuu expire at: 2024-07-26 00:07:28\n", + " - Token: 431****2ho expire at: 2024-07-25 19:41:25\n", + " - Token: 6v8****ji5 expire at: 2024-07-25 19:51:21\n", + " - Token: 5m8****uvp expire at: 2024-07-26 20:51:57\n", + " - Token: cs0****o3o expire at: 2024-07-26 21:45:40\n", + " - Token: nkv****i4h expire at: 2024-07-28 14:04:54\n", + " - Token: rvn****qp4 expire at: 2024-07-26 05:26:44\n", + " - Token: reu****rdm expire at: 2024-07-25 19:05:06\n", + " - Token: vv8****14b expire at: 2024-07-31 16:59:01\n", + " - Token: ogl****vkp expire at: 2024-07-28 17:19:41\n", + " - Token: 2ih****552 expire at: 2024-08-02 16:22:59\n", + " - Token: p7o****fl8 expire at: 2024-08-10 17:13:45\n", + " - Token: 0s3****0sm expire at: 2024-07-24 20:54:13\n", + " - Token: ajv****6du expire at: 2024-07-26 04:35:33\n", + " - Token: ved****ieq expire at: 2024-07-28 13:28:17\n", + " - Token: ooo****is3 expire at: 2024-07-26 21:48:25\n", + " - Token: 3ng****aas expire at: 2024-07-26 18:25:00\n", + " - Token: d4u****feg expire at: 2024-07-26 04:49:16\n", + " - Token: 8rl****746 expire at: 2024-07-31 17:54:35\n", + " - Token: rpn****jt7 expire at: 2024-07-25 19:00:55\n", + " - Token: eaf****9a6 expire at: 2024-07-25 23:33:40\n", + " - Token: m0a****dk3 expire at: 2024-08-11 15:38:47\n", + " - Token: 4gr****pi6 expire at: 2024-07-25 19:50:46\n", + " - Token: d8t****sap expire at: 2024-07-25 02:28:48\n", + " - Token: 3l2****ijm expire at: 2024-07-21 16:32:55\n", + " - Token: md5****3t6 expire at: 2024-07-27 20:15:07\n", + " - Token: 5v8****ft9 expire at: 2024-07-26 14:33:32\n", + " - Token: cd6****cjr expire at: 2024-07-26 21:02:57\n", + " - Token: 6kf****idh expire at: 2024-07-25 21:43:10\n", + " - Token: v4s****1ck expire at: 2024-07-26 13:43:41\n", + " - Token: haa****st1 expire at: 2024-08-11 03:09:16\n", + " - Token: 7d3****ors expire at: 2024-07-26 00:28:23\n", + " - Token: go7****u7o expire at: 2024-07-26 05:29:25\n", + " - Token: tuf****7i9 expire at: 2024-07-25 23:41:29\n", + " - Token: svv****tuf expire at: 2024-07-26 03:57:38\n", + " - Token: 9f3****1ac expire at: 2024-07-25 18:57:38\n", + " - Token: qr2****oj8 expire at: 2024-07-25 23:57:01\n", + " - Token: cdq****i4o expire at: 2024-07-28 18:13:17\n", + " - Token: 5ga****q04 expire at: 2024-07-28 16:59:56\n", + " - Token: vbu****qmb expire at: 2024-07-26 17:40:00\n", + " - Token: n7e****e5t expire at: 2024-08-11 16:55:13\n", + " - Token: t8n****h7g expire at: 2024-07-25 17:48:57\n", + " - Token: psa****kj8 expire at: 2024-07-26 21:34:10\n", + " - Token: tpu****h2k expire at: 2024-07-27 18:03:15\n", + " - Token: ih3****5kd expire at: 2024-07-25 21:03:16\n", + " - Token: 3el****b5g expire at: 2024-07-25 21:46:59\n", + " - Token: 3b7****7gj expire at: 2024-07-26 21:24:37\n", + " - Token: 380****gng expire at: 2024-07-28 14:04:02\n", + " - Token: mfj****mbd expire at: 2024-07-27 18:03:18\n", + " - Token: rhj****cbq expire at: 2024-07-21 16:44:57\n", + " - Token: s4n****5pv expire at: 2024-07-28 17:20:44\n", + " - Token: p4h****o58 expire at: 2024-07-26 00:07:16\n", + " - Token: kse****tob expire at: 2024-08-11 16:10:26\n", + " - Token: l55****5ol expire at: 2024-07-26 20:30:30\n", + " - Token: 9q2****l33 expire at: 2024-07-28 00:07:03\n", + " - Token: 8b0****ma1 expire at: 2024-08-11 15:25:00\n", + " - Token: oqd****gb7 expire at: 2024-07-26 20:41:53\n", + " - Token: rm2****aj6 expire at: 2024-07-31 17:44:38\n", + " - Token: gfu****iqd expire at: 2024-07-26 04:59:24\n", + " - Token: otr****0f9 expire at: 2024-07-25 22:42:23\n", + " - Token: pj7****j47 expire at: 2024-07-25 20:11:10\n", + " - Token: v2n****j6p expire at: 2024-07-27 11:01:55\n", + " - Token: tsb****74l expire at: 2024-07-28 15:17:29\n", + " - Token: 539****tmn expire at: 2024-07-28 19:23:25\n", + " - Token: 6r1****1u5 expire at: 2024-07-31 17:47:10\n", + " - Token: iun****fos expire at: 2024-07-28 17:18:54\n", + " - Token: ngv****7gu expire at: 2024-08-03 16:39:07\n", + " - Token: nf8****ic6 expire at: 2024-07-26 21:03:13\n", + " - Token: pli****uqa expire at: 2024-07-27 20:50:00\n", + " - Token: 12n****8gh expire at: 2024-07-21 16:42:15\n", + " - Token: ek9****ps9 expire at: 2024-07-31 17:28:46\n", + " - Token: t1f****k7i expire at: 2024-07-28 00:10:28\n", + " - Token: vk2****629 expire at: 2024-07-26 19:17:08\n", + " - Token: tev****3pd expire at: 2024-07-26 14:29:45\n", + " - Token: o4f****899 expire at: 2024-07-26 00:08:24\n", + " - Token: s82****fei expire at: 2024-07-21 16:15:29\n", + " - Token: rvr****350 expire at: 2024-07-25 22:08:48\n", + " - Token: t21****q84 expire at: 2024-07-21 16:13:53\n", + " - Token: qsk****22j expire at: 2024-07-28 16:17:11\n", + " - Token: 2c0****vtp expire at: 2024-07-26 14:06:50\n", + " - Token: 5v6****rcq expire at: 2024-07-26 21:01:56\n", + " - Token: jdm****qlb expire at: 2024-07-26 00:29:56\n", + " - Token: fe9****jtq expire at: 2024-07-31 17:39:01\n", + " - Token: ogl****th2 expire at: 2024-07-25 20:55:50\n", + " - Token: ar9****glu expire at: 2024-07-24 18:45:06\n", + " - Token: fi5****t3t expire at: 2024-07-26 21:02:02\n", + " - Token: pu8****1gu expire at: 2024-07-28 17:20:01\n", + " - Token: v0j****2c0 expire at: 2024-07-28 13:57:02\n", + " - Token: ttl****4pf expire at: 2024-07-24 16:49:27\n", + " - Token: d0t****b91 expire at: 2024-07-27 11:07:12\n", + " - Token: 3i7****scr expire at: 2024-07-28 11:16:03\n", + " - Token: 552****qlb expire at: 2024-08-03 17:35:51\n", + " - Token: h21****lqr expire at: 2024-07-25 22:47:37\n", + " - Token: 2e5****oll expire at: 2024-07-25 20:58:43\n", + " - Token: ggs****c3i expire at: 2024-07-25 22:07:29\n", + " - Token: cm0****m9p expire at: 2024-07-27 18:10:22\n", + " - Token: 8ur****thj expire at: 2024-07-31 17:10:27\n", + " - Token: nfr****8qu expire at: 2024-07-25 20:00:54\n", + " - Token: mt4****s9c expire at: 2024-07-26 13:35:14\n", + " - Token: tvc****kbq expire at: 2024-07-26 17:01:04\n", + " - Token: sbj****dlq expire at: 2024-07-26 00:06:33\n", + " - Token: sek****bcb expire at: 2024-08-03 16:02:51\n", + " - Token: ns4****njt expire at: 2024-07-25 22:43:53\n", + " - Token: eua****g1e expire at: 2024-07-28 17:19:18\n", + " - Token: 1fn****lc4 expire at: 2024-07-28 03:46:01\n", + " - Alias: AUTO_GENERATED_ALIAS_r4tqddc\n", + " - GraphName: Transaction_Fraud\n", + " - Secret: p65****3e4\n", + " - Token: f80****gdi expire at: 2024-08-11 18:20:22\n", + " - Alias: AUTO_GENERATED_ALIAS_p7mnb5e\n", + " - GraphName: TigerGraphRAG\n", + " - Secret: icf****nu0\n", + " - Token: 6ui****mb1 expire at: 2024-08-04 16:03:00\n", + " - Token: k3i****89q expire at: 2024-08-04 16:04:07\n", + " - Token: e6d****n3m expire at: 2024-07-28 17:45:08\n", + " - Token: 4d4****ubm expire at: 2024-07-28 17:45:25\n", + " - Token: e30****qam expire at: 2024-07-24 16:49:01\n", + " - Alias: AUTO_GENERATED_ALIAS_0ijfsnu\n", + " - GraphName: MyGraph\n", + " - Secret: ibm****i7f\n", + " - Token: oru****ucg expire at: 2024-08-15 02:05:49\n", + " - Token: 1ip****rg9 expire at: 2024-08-11 18:27:47\n", + " - Token: 1tg****qp0 expire at: 2024-08-15 02:03:27\n", + " - Token: h34****21t expire at: 2024-07-28 16:41:56\n", + " - Token: 418****iht expire at: 2024-08-10 21:35:24\n", + " - Token: om1****g7q expire at: 2024-08-03 19:49:39\n", + " - Token: dku****9so expire at: 2024-08-10 13:21:12\n", + " - Token: f88****be3 expire at: 2024-08-15 02:11:49\n", + " - Token: vhr****g7m expire at: 2024-08-11 18:30:03\n", + " - Token: qv8****qmb expire at: 2024-07-28 14:29:23\n", + " - Token: mfn****vvb expire at: 2024-07-28 14:44:37\n", + " - Token: ji2****mla expire at: 2024-08-04 15:57:47\n", + " - Token: 2vn****bmt expire at: 2024-08-10 21:08:51\n", + " - Token: fse****gm4 expire at: 2024-08-10 17:40:11\n", + " - Token: 0m1****cc4 expire at: 2024-08-09 21:27:39\n", + " - Token: cp0****d2s expire at: 2024-08-13 23:26:47\n", + " - Token: 9k2****99g expire at: 2024-08-04 15:09:21\n", + " - Token: 3db****gpe expire at: 2024-08-14 20:54:23\n", + " - Token: t8g****31s expire at: 2024-08-14 22:00:17\n", + " - Token: lia****0mu expire at: 2024-07-28 14:27:15\n", + " - Token: k1k****ubc expire at: 2024-07-28 17:00:50\n", + " - Token: d5p****d15 expire at: 2024-08-04 15:48:02\n", + " - Token: 3il****j1n expire at: 2024-08-14 20:52:49\n", + " - Token: de1****i4p expire at: 2024-08-11 17:09:11\n", + " - Token: ppa****5c1 expire at: 2024-08-11 20:14:44\n", + " - Token: v9h****ckd expire at: 2024-08-14 22:05:35\n", + " - Token: 6nn****h1k expire at: 2024-08-03 19:01:00\n", + " - Token: 6hg****0dd expire at: 2024-08-14 22:03:18\n", + " - Token: um0****pbc expire at: 2024-08-10 14:46:47\n", + " - Token: kk6****6dq expire at: 2024-08-05 03:01:07\n", + " - Token: s5u****4ih expire at: 2024-08-11 17:00:04\n", + " - Token: 3lf****qis expire at: 2024-08-10 13:22:07\n", + " - Token: mqf****qp8 expire at: 2024-08-03 19:38:25\n", + " - Token: l24****fja expire at: 2024-08-10 19:34:20\n", + " - Token: vnd****uri expire at: 2024-08-15 02:10:49\n", + " - Token: r9n****59h expire at: 2024-08-11 18:01:05\n", + " - Token: vh1****bg8 expire at: 2024-08-10 14:48:19\n", + " - Token: 4jo****kar expire at: 2024-08-11 20:45:09\n", + " - Token: mod****spb expire at: 2024-08-03 17:54:18\n", + " - Token: mls****kh1 expire at: 2024-08-10 16:01:23\n", + " - Token: e3r****8dh expire at: 2024-07-28 14:23:45\n", + " - Token: 4nc****5h3 expire at: 2024-08-10 14:48:22\n", + " - Token: 49u****1qk expire at: 2024-08-14 20:45:29\n", + " - Token: s92****iej expire at: 2024-07-28 16:32:01\n", + " - Token: fkr****hmn expire at: 2024-07-25 16:31:22\n", + " - Token: pd8****3ab expire at: 2024-08-03 16:46:47\n", + " - Token: o1g****2cd expire at: 2024-07-28 17:02:49\n", + " - Token: 79u****nvi expire at: 2024-08-10 21:52:23\n", + " - Token: ca0****37i expire at: 2024-07-28 16:38:32\n", + " - Token: g9t****h10 expire at: 2024-08-10 21:37:50\n", + " - Token: 5u7****uhn expire at: 2024-08-11 21:06:18\n", + " - Token: nq5****fbc expire at: 2024-07-25 15:16:53\n", + " - Token: ttc****gm7 expire at: 2024-08-03 17:55:09\n", + " - Token: k18****3cs expire at: 2024-08-10 21:07:50\n", + " - Token: 8ci****251 expire at: 2024-08-11 21:03:47\n", + " - Token: pcn****mqk expire at: 2024-08-10 14:54:44\n", + " - Token: 71r****o9p expire at: 2024-08-11 18:24:31\n", + " - Token: t8c****4ns expire at: 2024-07-28 16:38:56\n", + " - Token: ta0****498 expire at: 2024-08-09 21:05:25\n", + " - Token: 2os****vcq expire at: 2024-07-25 15:59:10\n", + " - Token: nfv****avu expire at: 2024-08-11 16:40:54\n", + " - Token: t09****r31 expire at: 2024-07-28 16:55:35\n", + " - Token: lc3****gi7 expire at: 2024-08-10 13:21:43\n", + " - Token: bbe****h49 expire at: 2024-07-25 15:10:42\n", + " - Token: phr****a22 expire at: 2024-08-14 22:05:40\n", + " - Token: eo8****kjh expire at: 2024-08-13 23:32:18\n", + " - Token: u54****rvb expire at: 2024-08-10 17:38:29\n", + " - Token: mb9****1bi expire at: 2024-08-04 17:56:00\n", + " - Token: mjn****9no expire at: 2024-08-09 20:46:47\n", + " - Token: 139****jjn expire at: 2024-07-28 14:46:27\n", + " - Token: 2m7****sp6 expire at: 2024-07-28 16:58:09\n", + " - Token: pit****oln expire at: 2024-07-28 17:01:38\n", + " - Token: 4mn****aa8 expire at: 2024-08-10 19:09:43\n", + " - Token: p08****0nm expire at: 2024-08-14 20:55:50\n", + " - Token: jj7****v0i expire at: 2024-08-02 19:16:02\n", + " - Token: 3s0****1lu expire at: 2024-08-03 10:59:40\n", + " - Token: 495****cvg expire at: 2024-07-28 17:49:47\n", + " - Token: 0ue****nep expire at: 2024-08-04 15:58:52\n", + " - Token: hhf****u5p expire at: 2024-08-11 17:09:21\n", + " - Token: c0q****vs3 expire at: 2024-08-11 17:02:42\n", + " - Token: hnt****tou expire at: 2024-08-11 20:40:15\n", + " - Token: qpq****qsb expire at: 2024-08-03 17:42:40\n", + " - Token: f66****vgs expire at: 2024-08-10 14:46:32\n", + " - Alias: AUTO_GENERATED_ALIAS_9gqutst\n", + " - GraphName: pyTigerGraphRAG\n", + " - LastSuccessLogin: Tue Jul 16 17:02:06 UTC 2024\n", + " - NextValidLogin: Tue Jul 16 17:02:06 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: dgarrigan\n", + " - LastSuccessLogin: Thu May 09 21:02:53 UTC 2024\n", + " - NextValidLogin: Thu May 09 21:02:53 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: user_1\n", + " - LastSuccessLogin: Fri Jun 14 18:04:17 UTC 2024\n", + " - NextValidLogin: Fri Jun 14 18:04:17 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: supawish.limprasert@tigergraph.com\n", + " - Global Roles: superuser\n", + " - Secret: j0t****7cv\n", + " - Alias: AUTO_GENERATED_ALIAS_r6kllut\n", + " - GraphName: Transaction_Fraud\n", + " - Secret: dou****sk7\n", + " - Alias: AUTO_GENERATED_ALIAS_ts7fee2\n", + " - GraphName: MyGraph\n", + " - LastSuccessLogin: Tue May 21 19:20:36 UTC 2024\n", + " - NextValidLogin: Tue May 21 19:20:36 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: victor.moey@tigergraph.com\n", + " - Global Roles: superuser\n", + " - Secret: d3h****394\n", + " - Alias: AUTO_GENERATED_ALIAS_r789a33\n", + " - GraphName: Transaction_Fraud\n", + " - Secret: 4ju****j60\n", + " - Alias: AUTO_GENERATED_ALIAS_fu6kd9p\n", + " - GraphName: MyGraph\n", + " - LastSuccessLogin: Fri May 31 20:22:12 UTC 2024\n", + " - NextValidLogin: Fri May 31 20:22:12 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: arshdeep.kaur@tigergraph.com\n", + " - Global Roles: superuser\n", + " - Secret: u6l****nmr\n", + " - Alias: AUTO_GENERATED_ALIAS_7q0hkpb\n", + " - GraphName: MyGraph\n", + " - LastSuccessLogin: Mon Jun 03 18:44:47 UTC 2024\n", + " - NextValidLogin: Mon Jun 03 18:44:47 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: lu.zhou@tigergraph.com\n", + " - Global Roles: superuser\n", + " - Secret: va0****b0s\n", + " - Token: 0ns****vuo expire at: 2024-07-18 16:20:54\n", + " - Token: jrh****pcv expire at: 2024-07-18 16:20:54\n", + " - Token: vag****t2d expire at: 2024-07-18 22:00:50\n", + " - Token: kgd****qej expire at: 2024-07-21 05:35:17\n", + " - Token: 4po****p18 expire at: 2024-07-24 19:48:08\n", + " - Token: oog****dbo expire at: 2024-07-19 17:06:19\n", + " - Token: o9l****sa2 expire at: 2024-07-19 06:13:58\n", + " - Token: itd****03k expire at: 2024-07-20 16:17:20\n", + " - Alias: AUTO_GENERATED_ALIAS_so4sd2c\n", + " - GraphName: Transaction_Fraud\n", + " - Secret: p9q****ifd\n", + " - Token: sp0****h0i expire at: 2024-07-18 22:00:44\n", + " - Token: 13b****8am expire at: 2024-08-09 19:37:09\n", + " - Token: rld****92k expire at: 2024-07-24 19:47:54\n", + " - Alias: AUTO_GENERATED_ALIAS_2a0lmf0\n", + " - GraphName: MyGraph\n", + " - LastSuccessLogin: Fri Jun 14 15:56:48 UTC 2024\n", + " - NextValidLogin: Fri Jun 14 15:56:48 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n", + " - Name: user_2\n", + " - Global Roles: superuser\n", + " - Graph 'Transaction_Fraud' Roles: admin\n", + " - Secret: 4re****k8d\n", + " - Token: l86****9pd expire at: 2024-07-19 15:07:25\n", + " - Token: hss****8hc expire at: 2024-07-19 15:18:01\n", + " - Token: 74f****0rg expire at: 2024-07-19 21:02:23\n", + " - Token: g3s****fiq expire at: 2024-07-18 21:08:00\n", + " - Token: 45c****e5j expire at: 2024-07-19 15:19:23\n", + " - Token: kk3****j58 expire at: 2024-07-19 14:33:50\n", + " - Token: gpa****ebi expire at: 2024-07-19 21:11:50\n", + " - Token: i3h****b18 expire at: 2024-07-19 14:32:33\n", + " - Token: 27q****kel expire at: 2024-07-19 14:46:03\n", + " - Token: jlb****ak2 expire at: 2024-07-19 15:24:57\n", + " - Token: hlj****kk5 expire at: 2024-07-19 19:35:58\n", + " - Token: r8l****r52 expire at: 2024-07-17 15:29:38\n", + " - Token: 6h8****35q expire at: 2024-07-20 15:25:50\n", + " - Token: 3sm****d5c expire at: 2024-07-18 21:18:31\n", + " - Token: 08p****dv9 expire at: 2024-07-18 21:07:34\n", + " - Token: 0mj****f4d expire at: 2024-07-17 15:29:38\n", + " - Token: r8u****i78 expire at: 2024-07-19 21:16:36\n", + " - Token: j26****p6q expire at: 2024-07-19 15:12:28\n", + " - Token: e3c****ht2 expire at: 2024-07-18 21:12:48\n", + " - Token: 2j0****g1v expire at: 2024-07-19 14:34:46\n", + " - Token: 9eo****th2 expire at: 2024-07-19 14:43:40\n", + " - Token: spr****0rs expire at: 2024-07-19 15:15:49\n", + " - Token: csb****e80 expire at: 2024-07-18 23:15:18\n", + " - Token: uku****90d expire at: 2024-07-19 14:37:01\n", + " - Token: p53****cav expire at: 2024-07-19 15:20:46\n", + " - Token: 414****rdh expire at: 2024-07-20 15:27:02\n", + " - Token: rv9****fjv expire at: 2024-07-19 21:06:57\n", + " - Token: mqd****grf expire at: 2024-07-19 14:49:09\n", + " - Token: fdu****kln expire at: 2024-07-18 21:10:31\n", + " - Token: 1dm****kma expire at: 2024-07-18 21:16:21\n", + " - Token: 2cq****80i expire at: 2024-07-20 15:26:13\n", + " - Token: h5b****4ap expire at: 2024-07-25 22:14:59\n", + " - Token: qis****4op expire at: 2024-07-20 15:26:38\n", + " - Alias: AUTO_GENERATED_ALIAS_02uaop4\n", + " - GraphName: Transaction_Fraud\n", + " - Secret: ecb****fce\n", + " - Token: p6b****kp9 expire at: 2024-07-26 13:26:53\n", + " - Token: 3a1****a5p expire at: 2024-07-25 21:49:27\n", + " - Alias: AUTO_GENERATED_ALIAS_4fcktc1\n", + " - GraphName: TigerGraphRAG\n", + " - Secret: ds5****gri\n", + " - Token: h6j****ajg expire at: 2024-07-18 13:17:19\n", + " - Token: bj2****qun expire at: 2024-07-17 21:24:51\n", + " - Token: o4s****94j expire at: 2024-08-11 13:00:04\n", + " - Token: k98****5ca expire at: 2024-07-17 21:24:26\n", + " - Token: 4s1****jlv expire at: 2024-07-18 00:43:29\n", + " - Token: t5u****71u expire at: 2024-07-25 13:01:56\n", + " - Token: ji4****3bs expire at: 2024-07-24 21:01:52\n", + " - Alias: AUTO_GENERATED_ALIAS_29i5m13\n", + " - GraphName: MyGraph\n", + " - Secret: 1oh****3p8\n", + " - Token: 7og****rtq expire at: 2024-07-27 05:27:53\n", + " - Token: gmk****fvs expire at: 2024-07-27 05:27:56\n", + " - Token: r94****t7m expire at: 2024-07-27 05:27:57\n", + " - Token: rdr****8iv expire at: 2024-07-25 16:37:12\n", + " - Token: 0ab****pro expire at: 2024-07-27 05:27:55\n", + " - Token: ql0****s8d expire at: 2024-07-26 17:37:06\n", + " - Token: 87e****d2s expire at: 2024-07-27 05:27:54\n", + " - Token: md3****mp8 expire at: 2024-07-25 13:08:26\n", + " - Token: 4fh****e46 expire at: 2024-07-27 12:59:08\n", + " - Token: j10****s4b expire at: 2024-07-26 13:46:49\n", + " - Token: qf1****05n expire at: 2024-07-27 13:31:41\n", + " - Token: ubj****ukd expire at: 2024-07-27 14:11:31\n", + " - Token: 6vl****3lb expire at: 2024-07-27 05:14:49\n", + " - Token: 5gq****qvb expire at: 2024-07-27 05:27:57\n", + " - Token: u32****0r5 expire at: 2024-07-27 13:22:04\n", + " - Token: s7d****ndh expire at: 2024-07-27 13:02:25\n", + " - Token: ek8****oil expire at: 2024-07-27 13:53:52\n", + " - Token: hev****e26 expire at: 2024-07-25 20:56:29\n", + " - Token: j8v****32g expire at: 2024-07-26 13:47:00\n", + " - Token: p08****vib expire at: 2024-07-27 13:34:32\n", + " - Token: jfd****orj expire at: 2024-07-27 05:27:54\n", + " - Token: bmh****b23 expire at: 2024-07-27 13:51:15\n", + " - Token: doe****21f expire at: 2024-07-25 16:16:48\n", + " - Token: bjq****2lm expire at: 2024-07-27 05:27:56\n", + " - Token: fba****fds expire at: 2024-07-27 13:26:42\n", + " - Token: iqh****8sc expire at: 2024-07-27 05:27:55\n", + " - Token: gm7****f4u expire at: 2024-07-27 05:18:22\n", + " - Token: c7b****2fg expire at: 2024-07-27 13:27:54\n", + " - Token: f4v****btu expire at: 2024-07-27 14:18:54\n", + " - Token: tjd****00b expire at: 2024-07-27 05:27:54\n", + " - Token: bif****90h expire at: 2024-07-27 13:25:00\n", + " - Token: d44****98l expire at: 2024-07-27 13:18:26\n", + " - Alias: AUTO_GENERATED_ALIAS_ohpig6e\n", + " - GraphName: pyTigerGraphRAG\n", + " - LastSuccessLogin: Tue Jul 02 21:26:28 UTC 2024\n", + " - NextValidLogin: Tue Jul 02 21:26:28 UTC 2024\n", + " - FailedAttempts: 0\n", + " - ShowAlterPasswordWarning: false\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "({'tigergraph': 'superuser',\n", + " 'parker.erickson@tigergraph.com': 'superuser',\n", + " 'zhixian.yan@tigergraph.com': 'superuser',\n", + " 'duc.hoai.le@tigergraph.com': 'superuser',\n", + " 'douglas.garrigan@tigergraph.com': 'superuser',\n", + " 'wyatt.joyner@tigergraph.com': 'superuser',\n", + " 'carl.boudreau@tigergraph.com': 'superuser',\n", + " 'alexander.thomas@tigergraph.com': 'superuser',\n", + " 'robert.rossmiller@tigergraph.com': 'superuser',\n", + " 'bill.shi@tigergraph.com': 'superuser',\n", + " 'yuling.liu@tigergraph.com': 'superuser',\n", + " 'kevin.stone@tigergraph.com': 'superuser',\n", + " 'supportai': 'superuser',\n", + " 'supawish.limprasert@tigergraph.com': 'superuser',\n", + " 'victor.moey@tigergraph.com': 'superuser',\n", + " 'arshdeep.kaur@tigergraph.com': 'superuser',\n", + " 'lu.zhou@tigergraph.com': 'superuser',\n", + " 'user_2': 'superuser'},\n", + " )" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import re\n", + "\n", + "from fastapi import HTTPException, status\n", + "from pyTigerGraph import TigerGraphConnection\n", + "# from app.common.config import db_config\n", + "\n", + "user_role_pattern = r'- Name:\\s+(.+?)\\s+- Global Roles:\\s+(.+?)\\s+-'\n", + "\n", + "def auth(username: str, password: str, conn=None) -> tuple[list[str], TigerGraphConnection]:\n", + " if conn is None:\n", + " conn = TigerGraphConnection(\n", + " # host=db_config[\"hostname\"], graphname=\"\", username=username, password=password\n", + " host=\"https://tg-26bfd0cd-6582-414e-937e-e2c83ecb5a79.us-east-1.i.tgcloud.io\",\n", + " graphname=\"\", username=username, password=password\n", + " )\n", + "\n", + " try:\n", + " # parse user info\n", + " info = conn.gsql(\"SHOW USER\")\n", + " user_roles = {}\n", + " print (info)\n", + " for match in re.finditer(user_role_pattern, info):\n", + " name = match.group(1).strip()\n", + " global_roles = match.group(2).strip()\n", + " user_roles[name] = global_roles\n", + "\n", + " except requests.exceptions.HTTPError as e:\n", + " raise HTTPException(\n", + " status_code=status.HTTP_401_UNAUTHORIZED,\n", + " detail=\"Incorrect username or password\",\n", + " )\n", + " except Exception as e:\n", + " raise e\n", + " return user_roles, conn\n", + "\n", + "auth(username=\"supportai\", password=\"supportai\")" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[\n", + " {\n", + " \"id\": 1,\n", + " \"create_ts\": \"2024-07-12T01:09:30.941010925Z\",\n", + " \"update_ts\": \"2024-07-12T01:09:30.941010925Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"5778f874-62e0-496b-a778-45a2a64ce4d0\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 2,\n", + " \"create_ts\": \"2024-07-12T01:13:33.506768718Z\",\n", + " \"update_ts\": \"2024-07-12T01:13:33.506768718Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"e31a8429-6b63-4777-ad68-f7ba06965eab\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 3,\n", + " \"create_ts\": \"2024-07-12T01:19:14.201770208Z\",\n", + " \"update_ts\": \"2024-07-12T01:19:14.201770208Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"8efe1d50-ed65-4e63-a3e7-b0470248d6e4\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 4,\n", + " \"create_ts\": \"2024-07-12T01:22:22.141025337Z\",\n", + " \"update_ts\": \"2024-07-12T01:22:22.141025337Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"051bb4d7-1e74-4e3e-90ae-8798d095cca6\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 5,\n", + " \"create_ts\": \"2024-07-12T03:37:53.87003471Z\",\n", + " \"update_ts\": \"2024-07-12T03:37:53.87003471Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"0475e8af-684b-4e5d-8ea9-ec074044d6f3\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 6,\n", + " \"create_ts\": \"2024-07-12T03:48:25.821287804Z\",\n", + " \"update_ts\": \"2024-07-12T03:48:25.821287804Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"27cbc602-cdc6-4805-bd81-faa63a7b165a\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 7,\n", + " \"create_ts\": \"2024-07-12T05:04:43.126749756Z\",\n", + " \"update_ts\": \"2024-07-12T05:04:43.126749756Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"c153b4be-d69e-43a3-b474-a15de40eb2c3\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 8,\n", + " \"create_ts\": \"2024-07-12T05:08:21.196420552Z\",\n", + " \"update_ts\": \"2024-07-12T05:08:21.196420552Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"6e05c4b1-6221-448f-8535-597fae556359\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 9,\n", + " \"create_ts\": \"2024-07-12T05:12:21.556408385Z\",\n", + " \"update_ts\": \"2024-07-12T05:12:21.556408385Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"e48f4c87-7427-4878-aeb8-a88a53210dfd\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 10,\n", + " \"create_ts\": \"2024-07-12T05:31:51.453909135Z\",\n", + " \"update_ts\": \"2024-07-12T05:31:51.453909135Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"dfde08fd-6c2d-4298-9f3d-ef1d382bbd95\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 11,\n", + " \"create_ts\": \"2024-07-12T05:35:48.387888759Z\",\n", + " \"update_ts\": \"2024-07-12T05:35:48.387888759Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"3984fe5f-45ae-4235-b22c-1963b1264077\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 12,\n", + " \"create_ts\": \"2024-07-12T05:44:22.915609052Z\",\n", + " \"update_ts\": \"2024-07-12T05:44:22.915609052Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"1db57ddb-0822-4d78-b21e-071955f0be7c\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 13,\n", + " \"create_ts\": \"2024-07-12T06:03:25.05808772Z\",\n", + " \"update_ts\": \"2024-07-12T06:03:25.05808772Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"6b892de8-8829-419a-9338-a4645bf8975d\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 14,\n", + " \"create_ts\": \"2024-07-12T06:07:44.474187757Z\",\n", + " \"update_ts\": \"2024-07-12T06:07:44.474187757Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"2581b958-afe1-40b8-9cbb-b344529d700e\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 15,\n", + " \"create_ts\": \"2024-07-12T06:17:15.128616757Z\",\n", + " \"update_ts\": \"2024-07-12T06:17:15.128616757Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"01923556-2957-44de-b2ba-608cbed239c8\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 16,\n", + " \"create_ts\": \"2024-07-12T06:24:59.34439018Z\",\n", + " \"update_ts\": \"2024-07-12T06:24:59.34439018Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"4a3763be-d84a-4fdd-ab9b-460c8025e03f\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 17,\n", + " \"create_ts\": \"2024-07-12T06:39:27.167549429Z\",\n", + " \"update_ts\": \"2024-07-12T06:39:27.167549429Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"91b7d06f-8e89-412d-a685-19071b13bfd2\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 18,\n", + " \"create_ts\": \"2024-07-12T06:41:30.811833792Z\",\n", + " \"update_ts\": \"2024-07-12T06:41:30.811833792Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"ec747115-ffe2-44cb-84bd-77fe966d828f\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 19,\n", + " \"create_ts\": \"2024-07-12T06:43:20.531792176Z\",\n", + " \"update_ts\": \"2024-07-12T06:43:20.531792176Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"f80cdd2a-89dc-4005-9494-a0f069a0e3c9\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 20,\n", + " \"create_ts\": \"2024-07-12T07:06:03.410195418Z\",\n", + " \"update_ts\": \"2024-07-12T07:06:03.410195418Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"81f3e1d7-b0b9-4492-ba64-a1c3a39d9840\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 21,\n", + " \"create_ts\": \"2024-07-12T07:31:58.792245971Z\",\n", + " \"update_ts\": \"2024-07-12T07:31:58.792245971Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"3c25a527-eb46-4a56-bc9d-705492fbedbc\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 22,\n", + " \"create_ts\": \"2024-07-12T08:06:04.311149305Z\",\n", + " \"update_ts\": \"2024-07-12T08:06:04.311149305Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"9d10b5cb-90a3-46ac-afab-0e8214a9def9\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 23,\n", + " \"create_ts\": \"2024-07-12T08:18:41.28110421Z\",\n", + " \"update_ts\": \"2024-07-12T08:18:41.28110421Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"7661baab-7ae4-4db4-a85d-fcc456590d87\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 24,\n", + " \"create_ts\": \"2024-07-12T08:22:01.357121887Z\",\n", + " \"update_ts\": \"2024-07-12T08:22:01.357121887Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"ba0518a6-b176-438a-a550-6b388dc25c14\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 25,\n", + " \"create_ts\": \"2024-07-12T08:23:57.618055093Z\",\n", + " \"update_ts\": \"2024-07-12T08:23:57.618055093Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"eaea7cf7-de32-484a-bcf7-a50f2e49ec99\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 26,\n", + " \"create_ts\": \"2024-07-12T08:29:16.947943005Z\",\n", + " \"update_ts\": \"2024-07-12T08:29:16.947943005Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"b063d493-e925-4c60-91fd-ce81080b02d7\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 27,\n", + " \"create_ts\": \"2024-07-12T08:54:38.647550709Z\",\n", + " \"update_ts\": \"2024-07-12T08:54:38.647550709Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"980e2438-11ba-4b1f-b77b-7276d855557b\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 28,\n", + " \"create_ts\": \"2024-07-12T09:04:17.060111255Z\",\n", + " \"update_ts\": \"2024-07-12T09:04:17.060111255Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"b5853229-d770-4103-b944-888deb8af1bd\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 29,\n", + " \"create_ts\": \"2024-07-12T09:17:17.643967922Z\",\n", + " \"update_ts\": \"2024-07-12T09:17:17.643967922Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"6f900ce2-e9d8-41ee-92ad-b337c4a71a8d\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 30,\n", + " \"create_ts\": \"2024-07-12T09:19:44.777980004Z\",\n", + " \"update_ts\": \"2024-07-12T09:19:44.777980004Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"532da9cb-0587-466f-b180-569144b8e5ad\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 31,\n", + " \"create_ts\": \"2024-07-12T15:47:41.095163511Z\",\n", + " \"update_ts\": \"2024-07-12T15:47:41.095163511Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"44750bd3-78a6-4f6e-b6de-1b3faeddfa2d\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 32,\n", + " \"create_ts\": \"2024-07-12T15:50:34.102892466Z\",\n", + " \"update_ts\": \"2024-07-12T15:50:34.102892466Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"212be4b5-e59b-48a7-bb2c-2ad59e4661a4\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 33,\n", + " \"create_ts\": \"2024-07-12T16:15:56.12926367Z\",\n", + " \"update_ts\": \"2024-07-12T16:15:56.12926367Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"3c628375-0b22-41d1-b231-87b4b7cc9eac\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 34,\n", + " \"create_ts\": \"2024-07-12T16:29:52.033069335Z\",\n", + " \"update_ts\": \"2024-07-12T16:29:52.033069335Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"ee6322c2-4916-4590-b592-df01cdce9054\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 35,\n", + " \"create_ts\": \"2024-07-12T16:42:21.648080543Z\",\n", + " \"update_ts\": \"2024-07-12T16:42:21.648080543Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"56a5138d-d4e5-493c-bcb2-35371e171dd0\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 36,\n", + " \"create_ts\": \"2024-07-12T16:49:12.511050886Z\",\n", + " \"update_ts\": \"2024-07-12T16:49:12.511050886Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"1f54367e-f481-4fda-b70b-c7c1cd1c2108\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 37,\n", + " \"create_ts\": \"2024-07-12T16:55:14.639173596Z\",\n", + " \"update_ts\": \"2024-07-12T16:55:14.639173596Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"fd125c22-2d5b-448b-9700-08073a74dff3\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 38,\n", + " \"create_ts\": \"2024-07-12T16:57:43.635279762Z\",\n", + " \"update_ts\": \"2024-07-12T16:57:43.635279762Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"40206d11-911f-4a8a-a90e-ecb78e8a076a\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 39,\n", + " \"create_ts\": \"2024-07-12T17:07:49.483211375Z\",\n", + " \"update_ts\": \"2024-07-12T17:07:49.483211375Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"e2795df0-2f29-4ce0-b56f-c5d6b58263e6\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 40,\n", + " \"create_ts\": \"2024-07-12T17:18:13.83835222Z\",\n", + " \"update_ts\": \"2024-07-12T17:18:13.83835222Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"d564c44d-4f96-4d0a-9c47-63bc97833664\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 41,\n", + " \"create_ts\": \"2024-07-12T17:35:06.945250967Z\",\n", + " \"update_ts\": \"2024-07-12T17:35:06.945250967Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"94a2456b-5e71-40d9-a145-9aa16a4ea964\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 42,\n", + " \"create_ts\": \"2024-07-12T17:40:02.980941548Z\",\n", + " \"update_ts\": \"2024-07-12T17:40:02.980941548Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"fe8c714a-9808-4d7b-8db7-d45bc9289776\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 43,\n", + " \"create_ts\": \"2024-07-12T17:43:59.425786005Z\",\n", + " \"update_ts\": \"2024-07-12T17:43:59.425786005Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"b1c23ed1-26e5-4f15-8eee-1092cec14458\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 44,\n", + " \"create_ts\": \"2024-07-12T17:46:13.640628803Z\",\n", + " \"update_ts\": \"2024-07-12T17:46:13.640628803Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"f6619dbb-777b-4c49-8719-a3dd7fa252d8\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 45,\n", + " \"create_ts\": \"2024-07-12T17:54:45.588624429Z\",\n", + " \"update_ts\": \"2024-07-12T17:54:45.588624429Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"01708f67-e553-43e4-b5cd-489a32c31f72\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 46,\n", + " \"create_ts\": \"2024-07-12T19:58:11.22233526Z\",\n", + " \"update_ts\": \"2024-07-12T19:58:11.22233526Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"a8cc1d9e-b01c-4c7b-bb7d-5284ea0038fa\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 47,\n", + " \"create_ts\": \"2024-07-12T21:04:29.768814424Z\",\n", + " \"update_ts\": \"2024-07-12T21:04:29.768814424Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"4d745509-3ab3-408a-a4a1-596cb7f56717\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 48,\n", + " \"create_ts\": \"2024-07-13T05:45:00.694247342Z\",\n", + " \"update_ts\": \"2024-07-13T05:45:00.694247342Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"676e1c45-3d82-40cf-8f78-b8c646c0169b\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 49,\n", + " \"create_ts\": \"2024-07-13T06:05:02.275046176Z\",\n", + " \"update_ts\": \"2024-07-13T06:05:02.275046176Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"84d93e14-2cfa-405d-8f9e-65d697812be9\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 50,\n", + " \"create_ts\": \"2024-07-13T06:15:00.605215383Z\",\n", + " \"update_ts\": \"2024-07-13T06:15:00.605215383Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"aa91756d-bd93-4d83-bf4a-b9f8439cb326\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 51,\n", + " \"create_ts\": \"2024-07-13T06:29:04.360870469Z\",\n", + " \"update_ts\": \"2024-07-13T06:29:04.360870469Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"240c3c12-544b-4739-a3c0-1c9bb110cb50\",\n", + " \"name\": \"\"\n", + " },\n", + " {\n", + " \"id\": 52,\n", + " \"create_ts\": \"2024-07-15T17:54:32.215517876Z\",\n", + " \"update_ts\": \"2024-07-15T17:54:32.215517876Z\",\n", + " \"delete_ts\": null,\n", + " \"user_id\": \"supportai\",\n", + " \"conversation_id\": \"06b077fe-5199-46fb-93b6-471ed7ae5277\",\n", + " \"name\": \"\"\n", + " }\n", + "]\n" + ] + } + ], + "source": [ + "import requests\n", + "import json\n", + "\n", + "headers = {\n", + " 'accept': 'application/json',\n", + " 'Authorization': 'Basic c3VwcG9ydGFpOnN1cHBvcnRhaQ=='\n", + "}\n", + "\n", + "user_id = \"supportai\"\n", + "\n", + "user_url = f'http://0.0.0.0:8000/ui/user/{user_id}'\n", + "\n", + "response = requests.get(user_url, headers=headers)\n", + "\n", + "if response.status_code == 200:\n", + " data = response.json()\n", + " print(json.dumps(data, indent=2))\n", + "else:\n", + " print(f\"Request failed with status code {response.status_code}\")\n", + " print(response.text) # Print the error message or response content" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[\n", + " {\n", + " \"id\": 273,\n", + " \"content\": \"Find all transactions, from 2/1/21 to 5/1/21 above average amount for that card. Sort the results.\",\n", + " \"feedback\": 0\n", + " },\n", + " {\n", + " \"id\": 274,\n", + " \"content\": \"The transactions from 2/1/21 to 5/1/21 that were above the average amount for that card are as follows: Transaction with id 39843 on 2021-04-17 with amount 7855.36, transaction with id 40831 on 2021-04-24 with amount 2934.13, transaction with id 871054 on 2021-02-02 with amount 5321.52, transaction with id 769 on 2021-04-17 with amount 2802.55, transaction with id 34336 on 2021-04-24 with amount 4935.42, transaction with id 473824 on 2021-04-18 with amount 3713.09, and transaction with id 7815 on 2021-04-17 with amount 6044.24.\",\n", + " \"feedback\": 0\n", + " },\n", + " {\n", + " \"id\": 275,\n", + " \"content\": \"Provide more details about this transaction 871054, like the card used and merchant involved in this transaction.\",\n", + " \"feedback\": 0\n", + " },\n", + " {\n", + " \"id\": 276,\n", + " \"content\": \"The transaction with the ID 871054 was a payment transaction that occurred at the time 2021-02-02 00:00:00. The amount involved in this transaction was 5321.52. The transaction was marked as fraudulent. However, the details about the card used and the merchant involved in this transaction are not provided in the given context.\",\n", + " \"feedback\": 0\n", + " },\n", + " {\n", + " \"id\": 277,\n", + " \"content\": \"what merchant is involved in the transaction 871054?\",\n", + " \"feedback\": 0\n", + " },\n", + " {\n", + " \"id\": 278,\n", + " \"content\": \"The merchant involved in the transaction 871054 is fraud_Kuhn LLC.\",\n", + " \"feedback\": 0\n", + " },\n", + " {\n", + " \"id\": 279,\n", + " \"content\": \"what card is used in the transaction 871054?\",\n", + " \"feedback\": 0\n", + " },\n", + " {\n", + " \"id\": 280,\n", + " \"content\": \"The context does not provide information on what card was used in transaction 871054.\",\n", + " \"feedback\": 0\n", + " },\n", + " {\n", + " \"id\": 281,\n", + " \"content\": \"List all merchants that have more than 2500 transactions from 2021-02-01 to 2021-10-01.\",\n", + " \"feedback\": 0\n", + " },\n", + " {\n", + " \"id\": 282,\n", + " \"content\": \"The merchants that have more than 2500 transactions from 2021-02-01 to 2021-10-01 are Kilback LLC with 2909 transactions and Kuhn LLC with 2610 transactions.\",\n", + " \"feedback\": 0\n", + " }\n", + "]\n" + ] + } + ], + "source": [ + "conversation_id = \"06b077fe-5199-46fb-93b6-471ed7ae5277\"\n", + "\n", + "conversation_url = f'http://0.0.0.0:8000/ui/conversation/{conversation_id}'\n", + "\n", + "response = requests.get(conversation_url, headers=headers)\n", + "\n", + "if response.status_code == 200:\n", + " conversation_data = []\n", + " data = response.json()\n", + " for message in data:\n", + " conversation_data.append({\n", + " \"id\": message[\"id\"],\n", + " \"content\": message[\"content\"],\n", + " \"feedback\": message[\"feedback\"]\n", + " })\n", + " \n", + " print(json.dumps(conversation_data, indent=2)) # For verification or further processing\n", + "else:\n", + " print(f\"Request failed with status code {response.status_code}\")\n", + " print(response.text) " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Topic 0:\n", + "merchant involved 2021-02-01 merchants average\n", + "Topic 1:\n", + "transaction card used transactions 2021-04-17\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/luzhou/Documents/github/CoPilot/venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:521: UserWarning: The parameter 'token_pattern' will not be used since 'tokenizer' is not None'\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "from sklearn.feature_extraction.text import CountVectorizer\n", + "from sklearn.decomposition import LatentDirichletAllocation\n", + "\n", + "# Extract feedback messages\n", + "feedback_messages = [item['content'] for item in conversation_data if item['feedback'] == 0]\n", + "\n", + "# Custom tokenizer to handle specific patterns\n", + "def custom_tokenizer(text):\n", + " # Split by non-alphanumeric characters\n", + " tokens = text.split()\n", + " # Remove numbers and tokens less than 3 characters long\n", + " tokens = [token for token in tokens if not token.isdigit() and len(token) > 2]\n", + " return tokens\n", + "\n", + "# Vectorize the feedback messages with custom tokenizer\n", + "vectorizer = CountVectorizer(stop_words='english', tokenizer=custom_tokenizer)\n", + "X = vectorizer.fit_transform(feedback_messages)\n", + "\n", + "# Fit LDA model\n", + "lda = LatentDirichletAllocation(n_components=2, random_state=42)\n", + "lda.fit(X)\n", + "\n", + "# Display topics\n", + "def display_topics(model, feature_names, num_top_words):\n", + " for topic_idx, topic in enumerate(model.components_):\n", + " print(f\"Topic {topic_idx}:\")\n", + " print(\" \".join([feature_names[i] for i in topic.argsort()[:-num_top_words - 1:-1]]))\n", + "\n", + "num_top_words = 5\n", + "feature_names = vectorizer.get_feature_names_out()\n", + "display_topics(lda, feature_names, num_top_words)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Clustering results:\n", + "Cluster 0:\n", + "- The transactions from 2/1/21 to 5/1/21 that were above the average amount for that card are as follows: Transaction with id 39843 on 2021-04-17 with amount 7855.36, transaction with id 40831 on 2021-04-24 with amount 2934.13, transaction with id 871054 on 2021-02-02 with amount 5321.52, transaction with id 769 on 2021-04-17 with amount 2802.55, transaction with id 34336 on 2021-04-24 with amount 4935.42, transaction with id 473824 on 2021-04-18 with amount 3713.09, and transaction with id 7815 on 2021-04-17 with amount 6044.24.\n", + "- Provide more details about this transaction 871054, like the card used and merchant involved in this transaction.\n", + "- The transaction with the ID 871054 was a payment transaction that occurred at the time 2021-02-02 00:00:00. The amount involved in this transaction was 5321.52. The transaction was marked as fraudulent. However, the details about the card used and the merchant involved in this transaction are not provided in the given context.\n", + "- what merchant is involved in the transaction 871054?\n", + "- The merchant involved in the transaction 871054 is fraud_Kuhn LLC.\n", + "- what card is used in the transaction 871054?\n", + "- The context does not provide information on what card was used in transaction 871054.\n", + "Cluster 1:\n", + "- Find all transactions, from 2/1/21 to 5/1/21 above average amount for that card. Sort the results.\n", + "- List all merchants that have more than 2500 transactions from 2021-02-01 to 2021-10-01.\n", + "- The merchants that have more than 2500 transactions from 2021-02-01 to 2021-10-01 are Kilback LLC with 2909 transactions and Kuhn LLC with 2610 transactions.\n", + "\n", + "Cluster centroids (top words per cluster):\n", + "Cluster 0 words: transaction 871054 involved merchant used card provide id fraud_kuhn context\n", + "Cluster 1 words: 01 transactions 2021 21 2500 10 merchants llc sort results\n" + ] + } + ], + "source": [ + "from sklearn.feature_extraction.text import TfidfVectorizer\n", + "from sklearn.cluster import KMeans\n", + "\n", + "# Extract feedback messages\n", + "feedback_messages = [item['content'] for item in conversation_data if item['feedback'] == 0]\n", + "\n", + "# Vectorize the feedback messages\n", + "vectorizer = TfidfVectorizer(stop_words='english')\n", + "X = vectorizer.fit_transform(feedback_messages)\n", + "\n", + "# Apply K-means clustering\n", + "num_clusters = 2 # Number of clusters\n", + "kmeans = KMeans(n_clusters=num_clusters, random_state=42)\n", + "kmeans.fit(X)\n", + "\n", + "# Print clustering results\n", + "print(\"Clustering results:\")\n", + "for i in range(num_clusters):\n", + " cluster_label = f\"Cluster {i}:\"\n", + " cluster_messages = [feedback_messages[j] for j in range(len(kmeans.labels_)) if kmeans.labels_[j] == i]\n", + " print(cluster_label)\n", + " for message in cluster_messages:\n", + " print(f\"- {message}\")\n", + "\n", + "# Optional: Print cluster centroids (important words for each cluster)\n", + "print(\"\\nCluster centroids (top words per cluster):\")\n", + "order_centroids = kmeans.cluster_centers_.argsort()[:, ::-1]\n", + "terms = vectorizer.get_feature_names_out()\n", + "for i in range(num_clusters):\n", + " print(f\"Cluster {i} words:\", end='')\n", + " for ind in order_centroids[i, :10]: # Print top 10 words per cluster\n", + " print(f' {terms[ind]}', end='')\n", + " print()\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From fd349567650037e4b9bbf6104b08ce0c36d77a65 Mon Sep 17 00:00:00 2001 From: Lu Zhou Date: Fri, 19 Jul 2024 16:03:47 -0700 Subject: [PATCH 2/3] GML-1815 hide credentials --- copilot/docs/notebooks/FeedbackAnalysis.ipynb | 1930 +++-------------- 1 file changed, 358 insertions(+), 1572 deletions(-) diff --git a/copilot/docs/notebooks/FeedbackAnalysis.ipynb b/copilot/docs/notebooks/FeedbackAnalysis.ipynb index dc1c0bef..3fb4adce 100644 --- a/copilot/docs/notebooks/FeedbackAnalysis.ipynb +++ b/copilot/docs/notebooks/FeedbackAnalysis.ipynb @@ -2,965 +2,29 @@ "cells": [ { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Users:\n", - " - Name: tigergraph\n", - " - Global Roles: superuser\n", - " - LastSuccessLogin: Tue Jul 16 17:02:03 UTC 2024\n", - " - NextValidLogin: Tue Jul 16 17:02:03 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: parker.erickson@tigergraph.com\n", - " - Global Roles: superuser\n", - " - Secret: r35****ure\n", - " - Token: uln****ej2 expire at: 2024-07-26 20:32:50\n", - " - Alias: AUTO_GENERATED_ALIAS_8giecm5\n", - " - GraphName: Transaction_Fraud\n", - " - Secret: 82p****27t\n", - " - Token: 19a****pq0 expire at: 2024-07-25 13:16:27\n", - " - Alias: AUTO_GENERATED_ALIAS_mmmqfdo\n", - " - GraphName: MyGraph\n", - " - Secret: d19****3j3\n", - " - Token: jds****ho3 expire at: 2024-07-25 13:16:47\n", - " - Token: vnf****26n expire at: 2024-07-25 23:49:57\n", - " - Token: ueq****big expire at: 2024-07-25 13:16:47\n", - " - Token: vin****83a expire at: 2024-07-25 16:26:52\n", - " - Token: mg7****er9 expire at: 2024-07-27 17:17:29\n", - " - Token: iev****k0r expire at: 2024-08-11 15:30:04\n", - " - Token: lbh****5c9 expire at: 2024-07-26 13:07:42\n", - " - Token: diu****6nl expire at: 2024-07-25 16:13:47\n", - " - Alias: AUTO_GENERATED_ALIAS_3nd4ejm\n", - " - GraphName: pyTigerGraphRAG\n", - " - LastSuccessLogin: Wed May 08 13:01:28 UTC 2024\n", - " - NextValidLogin: Wed May 08 13:01:28 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: zhixian.yan@tigergraph.com\n", - " - Global Roles: superuser\n", - " - LastSuccessLogin: Wed May 08 13:03:23 UTC 2024\n", - " - NextValidLogin: Wed May 08 13:03:23 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: duc.hoai.le@tigergraph.com\n", - " - Global Roles: superuser\n", - " - Secret: mm6****03t\n", - " - Token: bo1****0on expire at: 2024-07-17 20:07:07\n", - " - Token: b4d****omu expire at: 2024-07-17 20:48:13\n", - " - Token: r05****b22 expire at: 2024-07-19 00:01:03\n", - " - Token: g22****tpm expire at: 2024-07-17 20:47:33\n", - " - Token: t4n****va8 expire at: 2024-08-11 01:31:20\n", - " - Alias: AUTO_GENERATED_ALIAS_gioopv6\n", - " - GraphName: MyGraph\n", - " - LastSuccessLogin: Wed May 08 13:03:23 UTC 2024\n", - " - NextValidLogin: Wed May 08 13:03:23 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: douglas.garrigan@tigergraph.com\n", - " - Global Roles: superuser\n", - " - Secret: p1g****acg\n", - " - Token: g7v****01g expire at: 2024-07-19 23:11:06\n", - " - Token: blk****0c6 expire at: 2024-07-20 01:07:53\n", - " - Token: hi8****974 expire at: 2024-07-28 17:50:41\n", - " - Token: oiu****6i8 expire at: 2024-07-27 20:29:21\n", - " - Token: pkq****igc expire at: 2024-07-25 03:00:31\n", - " - Token: 9sr****ln4 expire at: 2024-07-27 20:27:33\n", - " - Token: o2t****61m expire at: 2024-07-25 03:02:48\n", - " - Token: 0a1****b3i expire at: 2024-07-21 02:37:52\n", - " - Alias: AUTO_GENERATED_ALIAS_fa9hmth\n", - " - GraphName: Transaction_Fraud\n", - " - Secret: sjl****245\n", - " - Token: rp0****qfc expire at: 2024-07-27 20:27:30\n", - " - Token: 8dr****o3b expire at: 2024-07-19 23:08:49\n", - " - Token: tsc****kh0 expire at: 2024-07-20 01:05:17\n", - " - Token: imq****g28 expire at: 2024-07-25 03:00:07\n", - " - Token: 5i6****e5t expire at: 2024-07-23 10:56:05\n", - " - Token: a5k****ms6 expire at: 2024-07-28 17:50:09\n", - " - Alias: AUTO_GENERATED_ALIAS_2jgiecd\n", - " - GraphName: MyGraph\n", - " - Secret: q6u****9mm\n", - " - Token: eni****5cb expire at: 2024-07-28 17:51:23\n", - " - Alias: AUTO_GENERATED_ALIAS_n6coqt4\n", - " - GraphName: pyTigerGraphRAG\n", - " - LastSuccessLogin: Wed May 08 13:03:24 UTC 2024\n", - " - NextValidLogin: Wed May 08 13:03:24 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: wyatt.joyner@tigergraph.com\n", - " - Global Roles: superuser\n", - " - LastSuccessLogin: Wed May 08 13:03:24 UTC 2024\n", - " - NextValidLogin: Wed May 08 13:03:24 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: carl.boudreau@tigergraph.com\n", - " - Global Roles: superuser\n", - " - LastSuccessLogin: Wed May 08 13:03:25 UTC 2024\n", - " - NextValidLogin: Wed May 08 13:03:25 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: alexander.thomas@tigergraph.com\n", - " - Global Roles: superuser\n", - " - LastSuccessLogin: Wed May 08 13:03:26 UTC 2024\n", - " - NextValidLogin: Wed May 08 13:03:26 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: robert.rossmiller@tigergraph.com\n", - " - Global Roles: superuser\n", - " - Secret: 819****0nu\n", - " - Alias: AUTO_GENERATED_ALIAS_poimof6\n", - " - GraphName: Transaction_Fraud\n", - " - Secret: o7k****ulg\n", - " - Token: 70t****45s expire at: 2024-07-26 16:41:47\n", - " - Token: cmq****4o3 expire at: 2024-07-25 21:46:37\n", - " - Token: n81****4b0 expire at: 2024-07-25 21:46:38\n", - " - Token: 36d****6qt expire at: 2024-07-26 16:41:48\n", - " - Alias: AUTO_GENERATED_ALIAS_n7kg136\n", - " - GraphName: TigerGraphRAG\n", - " - Secret: qoh****0os\n", - " - Token: v36****d5i expire at: 2024-07-24 17:44:46\n", - " - Token: a1m****h9n expire at: 2024-07-24 23:42:02\n", - " - Token: 0it****lfi expire at: 2024-07-17 15:10:42\n", - " - Token: 4t6****48s expire at: 2024-07-20 18:53:26\n", - " - Alias: AUTO_GENERATED_ALIAS_j0frhbm\n", - " - GraphName: MyGraph\n", - " - Secret: m5o****bar\n", - " - Token: l82****bur expire at: 2024-07-25 16:23:42\n", - " - Token: eal****rsc expire at: 2024-07-25 16:07:44\n", - " - Token: mgk****pao expire at: 2024-07-25 16:07:44\n", - " - Token: h77****h1r expire at: 2024-07-25 16:23:43\n", - " - Token: 9s0****5ec expire at: 2024-07-25 13:05:55\n", - " - Token: 0oo****npr expire at: 2024-07-25 13:05:56\n", - " - Alias: AUTO_GENERATED_ALIAS_p6kkmmo\n", - " - GraphName: pyTigerGraphRAG\n", - " - LastSuccessLogin: Wed May 08 13:03:26 UTC 2024\n", - " - NextValidLogin: Wed May 08 13:03:26 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: bill.shi@tigergraph.com\n", - " - Global Roles: superuser\n", - " - Secret: dak****n4k\n", - " - Alias: AUTO_GENERATED_ALIAS_164iqak\n", - " - GraphName: Transaction_Fraud\n", - " - Secret: 1tl****une\n", - " - Token: s7h****ql1 expire at: 2024-07-24 16:44:33\n", - " - Token: kup****8t9 expire at: 2024-07-24 01:02:03\n", - " - Token: jav****14h expire at: 2024-07-24 04:29:53\n", - " - Token: c3v****h41 expire at: 2024-08-09 17:36:49\n", - " - Token: ils****qfq expire at: 2024-07-25 22:07:34\n", - " - Alias: AUTO_GENERATED_ALIAS_uift7s8\n", - " - GraphName: MyGraph\n", - " - Secret: cio****1rm\n", - " - Token: aid****993 expire at: 2024-08-09 17:36:52\n", - " - Alias: AUTO_GENERATED_ALIAS_2e5g1jb\n", - " - GraphName: pyTigerGraphRAG\n", - " - LastSuccessLogin: Wed May 08 13:03:27 UTC 2024\n", - " - NextValidLogin: Wed May 08 13:03:27 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: yuling.liu@tigergraph.com\n", - " - Global Roles: superuser\n", - " - LastSuccessLogin: Wed May 08 13:03:28 UTC 2024\n", - " - NextValidLogin: Wed May 08 13:03:28 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: kevin.stone@tigergraph.com\n", - " - Global Roles: superuser\n", - " - LastSuccessLogin: Wed May 08 13:03:28 UTC 2024\n", - " - NextValidLogin: Wed May 08 13:03:28 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - "* - Name: supportai\n", - " - Global Roles: superuser\n", - " - Secret: gj6****erl\n", - " - Token: kbi****5vk expire at: 2024-07-26 14:37:39\n", - " - Token: 2a8****geq expire at: 2024-07-27 20:51:15\n", - " - Token: i9j****4lq expire at: 2024-07-25 20:41:12\n", - " - Token: emc****gmi expire at: 2024-07-28 15:12:52\n", - " - Token: tq6****is5 expire at: 2024-07-26 21:35:52\n", - " - Token: i3k****2pi expire at: 2024-07-25 20:06:54\n", - " - Token: 0nr****un6 expire at: 2024-07-26 21:48:36\n", - " - Token: lt9****4lv expire at: 2024-07-28 11:04:42\n", - " - Token: 7f7****j5g expire at: 2024-07-24 18:58:16\n", - " - Token: db2****aho expire at: 2024-07-27 20:29:54\n", - " - Token: t6r****5js expire at: 2024-07-25 20:32:16\n", - " - Token: a3s****94s expire at: 2024-07-26 20:00:56\n", - " - Token: v77****cfd expire at: 2024-07-25 21:24:57\n", - " - Token: he0****cdm expire at: 2024-08-11 18:30:53\n", - " - Token: 8v3****03q expire at: 2024-07-21 16:45:22\n", - " - Token: 8pj****73j expire at: 2024-07-26 00:13:31\n", - " - Token: nro****5fv expire at: 2024-07-25 21:24:41\n", - " - Token: vnu****ptn expire at: 2024-08-03 11:00:45\n", - " - Token: n2e****p8b expire at: 2024-08-07 19:16:40\n", - " - Token: uk7****1tn expire at: 2024-07-26 19:27:55\n", - " - Token: 4cn****ik8 expire at: 2024-07-25 20:54:56\n", - " - Token: o66****qdt expire at: 2024-07-26 19:09:04\n", - " - Token: j2s****d5o expire at: 2024-07-28 17:03:35\n", - " - Token: mqm****r1l expire at: 2024-07-26 00:07:37\n", - " - Token: pge****hig expire at: 2024-08-04 16:17:36\n", - " - Token: 0qa****qr6 expire at: 2024-07-25 03:52:04\n", - " - Token: dvd****4fg expire at: 2024-07-25 22:27:32\n", - " - Token: ve0****1vb expire at: 2024-07-25 20:58:27\n", - " - Token: f0q****7bs expire at: 2024-07-27 18:13:18\n", - " - Token: gom****2c9 expire at: 2024-07-21 08:12:01\n", - " - Token: kd8****7ie expire at: 2024-08-02 15:58:20\n", - " - Token: ar5****gbp expire at: 2024-08-04 16:16:32\n", - " - Token: lkc****drk expire at: 2024-07-26 19:00:54\n", - " - Token: akt****cch expire at: 2024-07-26 20:42:25\n", - " - Token: 35f****6pe expire at: 2024-07-25 22:53:37\n", - " - Token: a22****5sj expire at: 2024-07-25 20:49:06\n", - " - Token: hec****bkc expire at: 2024-07-25 23:00:06\n", - " - Token: o84****d8k expire at: 2024-07-27 20:50:07\n", - " - Token: 74i****1e2 expire at: 2024-07-21 08:03:17\n", - " - Token: ask****83l expire at: 2024-07-25 19:56:46\n", - " - Token: 786****eg6 expire at: 2024-07-26 04:55:53\n", - " - Token: s8a****cio expire at: 2024-08-03 15:49:25\n", - " - Token: 506****ua6 expire at: 2024-07-28 13:51:54\n", - " - Token: 973****ggo expire at: 2024-07-28 15:51:59\n", - " - Token: 831****925 expire at: 2024-07-26 20:08:09\n", - " - Token: 335****sm4 expire at: 2024-07-21 07:29:52\n", - " - Token: klp****b0u expire at: 2024-07-25 22:15:55\n", - " - Token: j18****97v expire at: 2024-07-26 03:29:46\n", - " - Token: 2er****i5q expire at: 2024-08-11 02:13:42\n", - " - Token: j79****irv expire at: 2024-07-28 15:38:49\n", - " - Token: lg2****h6k expire at: 2024-07-26 14:07:09\n", - " - Token: vqr****96m expire at: 2024-07-25 20:11:13\n", - " - Token: 5tg****cne expire at: 2024-07-31 16:45:19\n", - " - Token: 218****l8f expire at: 2024-07-25 21:47:41\n", - " - Token: 5g9****103 expire at: 2024-07-26 21:34:46\n", - " - Token: ak5****8t9 expire at: 2024-07-26 21:34:12\n", - " - Token: 6fg****5pt expire at: 2024-07-26 03:53:05\n", - " - Token: tn7****nmm expire at: 2024-07-26 04:39:38\n", - " - Token: 2f3****aam expire at: 2024-07-25 19:24:09\n", - " - Token: tmn****icm expire at: 2024-08-11 19:37:31\n", - " - Token: fll****t3o expire at: 2024-07-26 20:26:46\n", - " - Token: i33****0o7 expire at: 2024-07-26 00:13:34\n", - " - Token: 399****qcr expire at: 2024-07-25 22:38:13\n", - " - Token: mi6****ljc expire at: 2024-07-24 20:53:36\n", - " - Token: ve9****eco expire at: 2024-07-28 14:58:07\n", - " - Token: t3n****tgs expire at: 2024-07-26 18:59:36\n", - " - Token: 129****rnc expire at: 2024-07-27 20:56:21\n", - " - Token: cqb****beq expire at: 2024-08-04 17:51:07\n", - " - Token: k1a****ds2 expire at: 2024-08-11 15:17:15\n", - " - Token: 22l****fgv expire at: 2024-08-03 19:16:23\n", - " - Token: uov****soo expire at: 2024-07-25 19:16:17\n", - " - Token: lm3****oat expire at: 2024-07-26 14:06:43\n", - " - Token: fgu****m4f expire at: 2024-07-25 22:45:49\n", - " - Token: les****l50 expire at: 2024-07-25 21:56:54\n", - " - Token: u80****eih expire at: 2024-07-25 19:47:36\n", - " - Token: vit****s6g expire at: 2024-07-21 07:23:57\n", - " - Token: qsh****dgh expire at: 2024-07-25 20:51:58\n", - " - Token: her****o73 expire at: 2024-07-25 20:48:59\n", - " - Token: stq****0cu expire at: 2024-07-26 21:02:00\n", - " - Token: js9****g76 expire at: 2024-07-27 20:29:49\n", - " - Token: fp5****0po expire at: 2024-07-21 08:13:13\n", - " - Token: ns6****r77 expire at: 2024-07-28 13:34:25\n", - " - Token: eo5****uq6 expire at: 2024-08-03 17:52:17\n", - " - Token: 7d6****sdv expire at: 2024-07-24 18:58:58\n", - " - Token: 2pa****dnj expire at: 2024-07-26 21:45:42\n", - " - Token: 95u****k2a expire at: 2024-07-27 22:38:41\n", - " - Token: 69g****ncs expire at: 2024-07-21 08:07:51\n", - " - Token: hj4****ntj expire at: 2024-07-27 22:41:42\n", - " - Token: hiq****5v4 expire at: 2024-07-21 08:14:24\n", - " - Token: 3po****fd9 expire at: 2024-07-26 13:43:29\n", - " - Token: b09****bm1 expire at: 2024-07-25 21:26:54\n", - " - Token: 6of****kfs expire at: 2024-08-11 02:18:26\n", - " - Token: n3e****cnn expire at: 2024-07-27 20:32:38\n", - " - Token: po8****ioj expire at: 2024-07-27 20:50:52\n", - " - Token: 1fk****7jb expire at: 2024-08-11 21:04:16\n", - " - Token: ft8****s3d expire at: 2024-07-25 21:11:54\n", - " - Token: pq0****a7g expire at: 2024-07-27 20:50:31\n", - " - Token: 50p****lpu expire at: 2024-07-28 14:47:40\n", - " - Token: oan****da9 expire at: 2024-08-04 15:15:26\n", - " - Token: 622****95g expire at: 2024-07-26 21:48:06\n", - " - Token: 4ga****kje expire at: 2024-07-25 20:49:29\n", - " - Token: brc****v9s expire at: 2024-07-26 00:08:15\n", - " - Token: mu4****v7q expire at: 2024-07-27 20:33:49\n", - " - Token: n3q****ubo expire at: 2024-07-26 20:41:27\n", - " - Token: 1u5****lbq expire at: 2024-07-26 21:36:06\n", - " - Token: cup****cv0 expire at: 2024-07-25 22:54:09\n", - " - Token: 6hu****bvh expire at: 2024-07-25 21:21:36\n", - " - Token: ah7****o2n expire at: 2024-08-02 23:26:12\n", - " - Token: ip2****n5r expire at: 2024-07-25 19:00:02\n", - " - Token: 1dk****djm expire at: 2024-07-31 23:40:20\n", - " - Token: rli****t3m expire at: 2024-07-25 20:10:09\n", - " - Token: m7t****v4r expire at: 2024-07-28 17:18:03\n", - " - Token: ebp****p7j expire at: 2024-07-25 22:13:30\n", - " - Token: 9bt****686 expire at: 2024-07-27 23:05:50\n", - " - Token: u1i****8o1 expire at: 2024-07-28 18:34:12\n", - " - Token: r3r****pb0 expire at: 2024-07-26 03:43:31\n", - " - Token: uug****i4n expire at: 2024-08-11 15:18:18\n", - " - Token: br6****c8t expire at: 2024-07-24 20:54:50\n", - " - Token: k66****rer expire at: 2024-07-26 19:16:58\n", - " - Token: 765****mg8 expire at: 2024-07-25 21:26:41\n", - " - Token: mh8****lvh expire at: 2024-07-26 21:35:13\n", - " - Token: 1c2****16e expire at: 2024-07-26 14:33:05\n", - " - Token: frg****d84 expire at: 2024-07-25 19:38:31\n", - " - Token: ddr****5s0 expire at: 2024-07-26 00:07:48\n", - " - Token: fab****104 expire at: 2024-07-25 21:18:45\n", - " - Token: ovj****r8f expire at: 2024-07-25 22:30:59\n", - " - Token: ujc****s74 expire at: 2024-07-28 15:53:06\n", - " - Token: beo****tlc expire at: 2024-07-26 14:33:46\n", - " - Token: 48e****l3v expire at: 2024-07-31 17:49:58\n", - " - Token: ukp****5bd expire at: 2024-07-21 15:59:05\n", - " - Token: n8h****pag expire at: 2024-07-26 00:29:47\n", - " - Token: a9p****bc0 expire at: 2024-07-24 20:59:53\n", - " - Token: rbn****1ul expire at: 2024-07-28 18:10:16\n", - " - Token: 7cq****jif expire at: 2024-07-26 04:35:24\n", - " - Token: iul****h6i expire at: 2024-07-25 20:59:47\n", - " - Token: sb1****q5u expire at: 2024-08-03 19:32:22\n", - " - Token: n6t****eu6 expire at: 2024-07-25 21:42:30\n", - " - Token: 7mb****g6h expire at: 2024-07-26 13:34:31\n", - " - Token: t9s****thq expire at: 2024-07-25 20:22:28\n", - " - Token: c59****l4i expire at: 2024-07-26 04:52:22\n", - " - Token: 6j5****coe expire at: 2024-07-25 20:41:50\n", - " - Token: kth****o81 expire at: 2024-07-25 20:41:40\n", - " - Token: fse****rd1 expire at: 2024-07-25 22:07:03\n", - " - Token: oq0****a5q expire at: 2024-07-21 16:49:17\n", - " - Token: bmm****08m expire at: 2024-07-28 15:51:35\n", - " - Token: u0l****u1b expire at: 2024-07-21 07:03:19\n", - " - Token: rl2****i2b expire at: 2024-07-27 18:12:10\n", - " - Token: a5l****df6 expire at: 2024-07-24 18:48:41\n", - " - Token: 5t9****qfd expire at: 2024-07-24 23:12:44\n", - " - Token: 73e****7ve expire at: 2024-07-26 13:43:08\n", - " - Token: 33o****q82 expire at: 2024-07-25 20:17:13\n", - " - Token: 9i0****d7c expire at: 2024-07-26 20:41:31\n", - " - Token: 3nm****9aq expire at: 2024-07-26 00:03:11\n", - " - Token: sim****kfk expire at: 2024-07-25 17:44:47\n", - " - Token: 5po****ci7 expire at: 2024-07-28 15:46:47\n", - " - Token: u07****r4q expire at: 2024-07-25 22:13:55\n", - " - Token: 27g****jdp expire at: 2024-07-26 21:02:38\n", - " - Token: ok4****lqh expire at: 2024-08-03 17:28:26\n", - " - Token: ec9****kol expire at: 2024-08-11 18:49:25\n", - " - Token: vr0****1ud expire at: 2024-07-25 19:00:48\n", - " - Token: e1r****cin expire at: 2024-07-26 19:18:35\n", - " - Token: cm9****5da expire at: 2024-07-21 17:24:05\n", - " - Token: vr3****spq expire at: 2024-07-25 20:54:42\n", - " - Token: qe3****9uv expire at: 2024-07-25 20:09:40\n", - " - Token: pii****bfe expire at: 2024-07-25 17:43:45\n", - " - Token: 61c****fvu expire at: 2024-07-26 21:45:37\n", - " - Token: mqd****r9e expire at: 2024-07-25 20:44:53\n", - " - Token: enp****h8j expire at: 2024-08-10 20:48:59\n", - " - Token: fjv****4nv expire at: 2024-07-25 19:08:51\n", - " - Token: vor****2ki expire at: 2024-07-27 23:58:38\n", - " - Token: 6lb****4as expire at: 2024-07-26 00:08:36\n", - " - Token: q90****eu8 expire at: 2024-07-26 21:46:46\n", - " - Token: bil****sso expire at: 2024-08-03 11:00:43\n", - " - Token: nhf****hvr expire at: 2024-07-25 18:58:30\n", - " - Token: 486****1ei expire at: 2024-07-26 04:28:07\n", - " - Token: 73k****24i expire at: 2024-08-04 16:26:45\n", - " - Token: m5r****okj expire at: 2024-07-28 15:46:08\n", - " - Token: 70q****4dc expire at: 2024-07-21 08:06:42\n", - " - Token: i4e****k99 expire at: 2024-07-31 17:33:59\n", - " - Token: ku6****919 expire at: 2024-07-26 04:43:28\n", - " - Token: bce****hqk expire at: 2024-07-27 20:29:53\n", - " - Token: t51****t8l expire at: 2024-07-28 17:20:25\n", - " - Token: 5ao****6rr expire at: 2024-07-25 22:13:46\n", - " - Token: ukd****1rm expire at: 2024-07-21 16:43:56\n", - " - Token: v42****n1s expire at: 2024-07-26 16:18:32\n", - " - Token: g25****8ja expire at: 2024-07-26 20:24:35\n", - " - Token: ns2****sct expire at: 2024-08-11 01:19:12\n", - " - Token: adn****2bm expire at: 2024-07-25 20:10:37\n", - " - Token: pop****kic expire at: 2024-07-31 17:15:16\n", - " - Token: fvn****hm2 expire at: 2024-07-25 20:41:18\n", - " - Token: n1k****f3c expire at: 2024-07-26 17:18:42\n", - " - Token: ls7****m7f expire at: 2024-07-26 16:48:30\n", - " - Token: 79k****8bl expire at: 2024-07-26 20:54:48\n", - " - Token: 0mm****g6j expire at: 2024-07-31 23:51:19\n", - " - Token: 5hb****bo8 expire at: 2024-07-28 17:09:23\n", - " - Token: rcr****5vf expire at: 2024-07-26 20:21:14\n", - " - Token: 354****p55 expire at: 2024-07-25 21:26:00\n", - " - Token: 0nf****k3v expire at: 2024-07-21 14:54:03\n", - " - Token: 9jj****bho expire at: 2024-07-26 21:02:25\n", - " - Token: i5k****d9a expire at: 2024-07-31 17:17:18\n", - " - Token: u4e****90m expire at: 2024-08-03 15:44:59\n", - " - Token: p8n****r9s expire at: 2024-07-26 19:44:26\n", - " - Token: v13****m0d expire at: 2024-07-28 11:20:50\n", - " - Token: s66****mj4 expire at: 2024-08-04 15:36:37\n", - " - Token: pi5****19s expire at: 2024-07-26 03:26:03\n", - " - Token: c5a****1il expire at: 2024-07-28 14:07:24\n", - " - Token: u0q****1mb expire at: 2024-07-27 23:44:00\n", - " - Token: n2s****rfe expire at: 2024-07-28 11:23:06\n", - " - Token: 96c****ec2 expire at: 2024-08-11 02:39:54\n", - " - Token: 6h2****9tq expire at: 2024-07-27 18:12:32\n", - " - Token: ss1****tr7 expire at: 2024-07-25 19:30:12\n", - " - Token: gum****7sv expire at: 2024-07-25 19:33:37\n", - " - Token: 9bd****gk5 expire at: 2024-08-02 19:12:15\n", - " - Token: 73k****ca1 expire at: 2024-07-25 20:33:08\n", - " - Token: as9****p2l expire at: 2024-07-26 00:35:15\n", - " - Token: k1t****nij expire at: 2024-07-25 19:52:55\n", - " - Token: tna****6vj expire at: 2024-07-21 08:05:29\n", - " - Token: bce****fi0 expire at: 2024-07-26 04:24:24\n", - " - Token: tp8****c3a expire at: 2024-07-25 20:11:22\n", - " - Token: h83****9fc expire at: 2024-08-03 17:35:13\n", - " - Token: 807****5kd expire at: 2024-07-25 21:57:12\n", - " - Token: lbk****l1u expire at: 2024-08-10 22:03:48\n", - " - Token: ea9****2ji expire at: 2024-07-20 18:36:54\n", - " - Token: 8fp****moj expire at: 2024-08-11 13:48:47\n", - " - Token: k44****t2s expire at: 2024-07-27 23:19:49\n", - " - Token: qe2****mbl expire at: 2024-07-25 22:14:07\n", - " - Token: kjt****fmf expire at: 2024-07-26 00:06:49\n", - " - Token: en5****pd7 expire at: 2024-07-27 17:59:18\n", - " - Token: e9c****jum expire at: 2024-07-26 20:30:45\n", - " - Token: 10n****068 expire at: 2024-08-03 16:27:41\n", - " - Token: tbb****60q expire at: 2024-08-10 17:12:50\n", - " - Token: uva****aib expire at: 2024-07-27 22:30:45\n", - " - Token: 1vc****nrn expire at: 2024-08-04 16:15:29\n", - " - Token: 0u6****0r3 expire at: 2024-07-25 20:39:36\n", - " - Token: mgd****4k1 expire at: 2024-08-11 03:04:42\n", - " - Token: 7fr****nkq expire at: 2024-07-27 20:49:55\n", - " - Token: 5vo****gaf expire at: 2024-07-26 20:35:44\n", - " - Token: q1p****fpo expire at: 2024-07-26 19:44:29\n", - " - Token: ll3****qrt expire at: 2024-07-25 23:23:46\n", - " - Token: dj5****3j4 expire at: 2024-07-27 18:12:58\n", - " - Token: umr****17s expire at: 2024-07-27 20:51:42\n", - " - Token: ca8****pfe expire at: 2024-07-25 22:50:24\n", - " - Token: es1****orh expire at: 2024-07-26 18:59:51\n", - " - Token: nqf****qkp expire at: 2024-08-11 03:48:22\n", - " - Token: 0jq****dso expire at: 2024-07-26 05:22:21\n", - " - Token: mn5****ff6 expire at: 2024-08-11 02:54:50\n", - " - Token: 25p****kcv expire at: 2024-07-26 05:15:13\n", - " - Token: r4i****clo expire at: 2024-07-25 21:56:36\n", - " - Token: 010****1ci expire at: 2024-07-27 21:01:14\n", - " - Token: 46m****44d expire at: 2024-07-28 18:34:09\n", - " - Token: qj2****ec3 expire at: 2024-07-25 20:05:59\n", - " - Token: m65****erc expire at: 2024-07-25 21:12:11\n", - " - Token: e80****ek3 expire at: 2024-07-26 20:41:33\n", - " - Token: ifn****k7u expire at: 2024-07-28 10:57:10\n", - " - Token: bsr****5ob expire at: 2024-07-26 05:32:31\n", - " - Token: t8k****514 expire at: 2024-07-27 20:49:58\n", - " - Token: te4****inb expire at: 2024-07-21 16:29:55\n", - " - Token: hm6****971 expire at: 2024-08-11 14:22:18\n", - " - Token: vv4****f25 expire at: 2024-07-28 15:43:14\n", - " - Token: 5qr****i08 expire at: 2024-07-25 21:01:47\n", - " - Token: h9g****rfu expire at: 2024-07-25 21:56:59\n", - " - Token: 8bd****2bn expire at: 2024-07-26 21:35:26\n", - " - Token: v3u****t66 expire at: 2024-07-21 08:04:21\n", - " - Token: ec5****htp expire at: 2024-07-27 20:31:08\n", - " - Token: 4e3****173 expire at: 2024-07-28 13:44:01\n", - " - Token: ohr****iou expire at: 2024-08-12 05:44:48\n", - " - Token: de1****kp2 expire at: 2024-07-25 22:49:16\n", - " - Token: 8qv****amj expire at: 2024-07-25 02:29:34\n", - " - Token: 3te****k2t expire at: 2024-07-25 21:02:29\n", - " - Token: f0i****bql expire at: 2024-07-25 21:25:30\n", - " - Token: 76m****qji expire at: 2024-07-27 11:10:04\n", - " - Token: a4o****htr expire at: 2024-07-25 21:03:33\n", - " - Token: 716****bfg expire at: 2024-07-26 19:08:53\n", - " - Token: uuj****24b expire at: 2024-07-26 14:34:15\n", - " - Token: nkc****uti expire at: 2024-07-27 20:34:06\n", - " - Token: q4p****05g expire at: 2024-07-25 21:19:03\n", - " - Token: e13****260 expire at: 2024-07-25 20:18:06\n", - " - Token: ul9****msd expire at: 2024-08-03 11:06:29\n", - " - Token: f9f****tu4 expire at: 2024-07-25 20:09:58\n", - " - Token: bqn****076 expire at: 2024-07-26 00:07:02\n", - " - Token: aif****374 expire at: 2024-07-26 21:46:29\n", - " - Token: avf****att expire at: 2024-07-27 22:53:21\n", - " - Token: d5v****ai4 expire at: 2024-07-25 23:28:26\n", - " - Token: 0lu****b0j expire at: 2024-07-21 17:25:06\n", - " - Token: fqk****5bj expire at: 2024-07-25 22:16:09\n", - " - Token: abr****h3s expire at: 2024-07-21 08:02:24\n", - " - Token: ba3****q76 expire at: 2024-07-28 15:53:11\n", - " - Token: 28f****qat expire at: 2024-08-04 15:24:11\n", - " - Token: fco****769 expire at: 2024-07-25 19:48:26\n", - " - Token: pr5****4jb expire at: 2024-07-25 21:14:13\n", - " - Token: 3kh****92v expire at: 2024-07-26 19:21:36\n", - " - Token: hju****3pt expire at: 2024-07-28 17:17:42\n", - " - Token: 26i****gte expire at: 2024-07-25 18:19:16\n", - " - Token: d41****8b9 expire at: 2024-08-10 17:13:27\n", - " - Token: u57****uaa expire at: 2024-07-26 21:03:55\n", - " - Token: ld1****025 expire at: 2024-07-27 20:33:25\n", - " - Token: rmh****hjb expire at: 2024-07-31 23:28:08\n", - " - Token: 4co****o9f expire at: 2024-07-25 19:50:18\n", - " - Token: gs8****6al expire at: 2024-07-25 20:42:07\n", - " - Token: d2i****j9v expire at: 2024-07-21 16:31:26\n", - " - Token: 65h****d0p expire at: 2024-07-21 16:41:17\n", - " - Token: 0hd****qh7 expire at: 2024-08-11 15:36:49\n", - " - Token: vq2****rk9 expire at: 2024-07-25 20:02:06\n", - " - Token: nq2****0o2 expire at: 2024-07-26 14:34:03\n", - " - Token: 7jv****aak expire at: 2024-08-03 11:08:29\n", - " - Token: gag****qt1 expire at: 2024-07-28 13:54:04\n", - " - Token: g57****o24 expire at: 2024-07-21 16:43:12\n", - " - Token: mq8****fc3 expire at: 2024-07-28 15:49:59\n", - " - Token: 0t0****3t1 expire at: 2024-08-03 16:13:20\n", - " - Token: cvu****g01 expire at: 2024-07-25 20:55:13\n", - " - Token: 7s6****u9r expire at: 2024-07-25 17:46:03\n", - " - Token: 3lp****ium expire at: 2024-07-26 14:29:51\n", - " - Token: fkj****3gh expire at: 2024-07-26 20:30:59\n", - " - Token: imj****0lp expire at: 2024-07-25 23:10:20\n", - " - Token: d2c****9c0 expire at: 2024-07-26 20:53:22\n", - " - Token: igs****v9c expire at: 2024-08-04 16:05:57\n", - " - Token: rdp****332 expire at: 2024-07-25 20:45:59\n", - " - Token: 47u****bmk expire at: 2024-07-25 20:57:48\n", - " - Token: 95f****l13 expire at: 2024-07-25 23:36:25\n", - " - Token: 48e****r1r expire at: 2024-07-21 16:41:42\n", - " - Token: r3t****4qn expire at: 2024-07-27 20:51:59\n", - " - Token: fab****i0o expire at: 2024-07-28 17:18:05\n", - " - Token: g2m****fq7 expire at: 2024-07-26 00:28:10\n", - " - Token: aqo****c79 expire at: 2024-07-27 20:32:56\n", - " - Token: 0k5****bcc expire at: 2024-07-25 23:33:05\n", - " - Token: 84p****9au expire at: 2024-07-26 20:29:35\n", - " - Token: o2p****p9r expire at: 2024-07-25 23:38:23\n", - " - Token: ppm****g5a expire at: 2024-08-11 15:17:40\n", - " - Token: 5gp****9j0 expire at: 2024-07-26 21:24:49\n", - " - Token: 2fi****5n4 expire at: 2024-07-25 21:24:25\n", - " - Token: 3s9****hct expire at: 2024-07-26 20:42:08\n", - " - Token: 17e****etj expire at: 2024-07-27 22:50:34\n", - " - Token: ahf****39t expire at: 2024-07-25 20:18:57\n", - " - Token: uv3****f13 expire at: 2024-07-26 21:04:11\n", - " - Token: mem****b44 expire at: 2024-07-26 05:20:09\n", - " - Token: a55****hgj expire at: 2024-07-25 19:56:43\n", - " - Token: iba****7gh expire at: 2024-08-11 18:43:40\n", - " - Token: 09h****eb5 expire at: 2024-08-11 16:02:13\n", - " - Token: keq****7n0 expire at: 2024-07-28 18:18:18\n", - " - Token: 5cu****3in expire at: 2024-07-25 20:27:51\n", - " - Token: cr3****mn7 expire at: 2024-07-25 19:53:07\n", - " - Token: 5od****442 expire at: 2024-07-26 03:49:18\n", - " - Token: 32h****bo7 expire at: 2024-07-26 20:30:23\n", - " - Token: f6q****moo expire at: 2024-07-31 23:20:50\n", - " - Token: ndl****pma expire at: 2024-07-28 10:54:24\n", - " - Token: tsb****1tf expire at: 2024-07-26 00:03:15\n", - " - Token: net****9i1 expire at: 2024-08-03 19:53:36\n", - " - Token: 293****71o expire at: 2024-07-25 21:12:15\n", - " - Token: dpo****672 expire at: 2024-08-10 22:01:43\n", - " - Token: 7h4****g5d expire at: 2024-07-26 21:47:52\n", - " - Token: j89****g7s expire at: 2024-08-11 02:50:27\n", - " - Token: nt0****vuu expire at: 2024-07-26 00:07:28\n", - " - Token: 431****2ho expire at: 2024-07-25 19:41:25\n", - " - Token: 6v8****ji5 expire at: 2024-07-25 19:51:21\n", - " - Token: 5m8****uvp expire at: 2024-07-26 20:51:57\n", - " - Token: cs0****o3o expire at: 2024-07-26 21:45:40\n", - " - Token: nkv****i4h expire at: 2024-07-28 14:04:54\n", - " - Token: rvn****qp4 expire at: 2024-07-26 05:26:44\n", - " - Token: reu****rdm expire at: 2024-07-25 19:05:06\n", - " - Token: vv8****14b expire at: 2024-07-31 16:59:01\n", - " - Token: ogl****vkp expire at: 2024-07-28 17:19:41\n", - " - Token: 2ih****552 expire at: 2024-08-02 16:22:59\n", - " - Token: p7o****fl8 expire at: 2024-08-10 17:13:45\n", - " - Token: 0s3****0sm expire at: 2024-07-24 20:54:13\n", - " - Token: ajv****6du expire at: 2024-07-26 04:35:33\n", - " - Token: ved****ieq expire at: 2024-07-28 13:28:17\n", - " - Token: ooo****is3 expire at: 2024-07-26 21:48:25\n", - " - Token: 3ng****aas expire at: 2024-07-26 18:25:00\n", - " - Token: d4u****feg expire at: 2024-07-26 04:49:16\n", - " - Token: 8rl****746 expire at: 2024-07-31 17:54:35\n", - " - Token: rpn****jt7 expire at: 2024-07-25 19:00:55\n", - " - Token: eaf****9a6 expire at: 2024-07-25 23:33:40\n", - " - Token: m0a****dk3 expire at: 2024-08-11 15:38:47\n", - " - Token: 4gr****pi6 expire at: 2024-07-25 19:50:46\n", - " - Token: d8t****sap expire at: 2024-07-25 02:28:48\n", - " - Token: 3l2****ijm expire at: 2024-07-21 16:32:55\n", - " - Token: md5****3t6 expire at: 2024-07-27 20:15:07\n", - " - Token: 5v8****ft9 expire at: 2024-07-26 14:33:32\n", - " - Token: cd6****cjr expire at: 2024-07-26 21:02:57\n", - " - Token: 6kf****idh expire at: 2024-07-25 21:43:10\n", - " - Token: v4s****1ck expire at: 2024-07-26 13:43:41\n", - " - Token: haa****st1 expire at: 2024-08-11 03:09:16\n", - " - Token: 7d3****ors expire at: 2024-07-26 00:28:23\n", - " - Token: go7****u7o expire at: 2024-07-26 05:29:25\n", - " - Token: tuf****7i9 expire at: 2024-07-25 23:41:29\n", - " - Token: svv****tuf expire at: 2024-07-26 03:57:38\n", - " - Token: 9f3****1ac expire at: 2024-07-25 18:57:38\n", - " - Token: qr2****oj8 expire at: 2024-07-25 23:57:01\n", - " - Token: cdq****i4o expire at: 2024-07-28 18:13:17\n", - " - Token: 5ga****q04 expire at: 2024-07-28 16:59:56\n", - " - Token: vbu****qmb expire at: 2024-07-26 17:40:00\n", - " - Token: n7e****e5t expire at: 2024-08-11 16:55:13\n", - " - Token: t8n****h7g expire at: 2024-07-25 17:48:57\n", - " - Token: psa****kj8 expire at: 2024-07-26 21:34:10\n", - " - Token: tpu****h2k expire at: 2024-07-27 18:03:15\n", - " - Token: ih3****5kd expire at: 2024-07-25 21:03:16\n", - " - Token: 3el****b5g expire at: 2024-07-25 21:46:59\n", - " - Token: 3b7****7gj expire at: 2024-07-26 21:24:37\n", - " - Token: 380****gng expire at: 2024-07-28 14:04:02\n", - " - Token: mfj****mbd expire at: 2024-07-27 18:03:18\n", - " - Token: rhj****cbq expire at: 2024-07-21 16:44:57\n", - " - Token: s4n****5pv expire at: 2024-07-28 17:20:44\n", - " - Token: p4h****o58 expire at: 2024-07-26 00:07:16\n", - " - Token: kse****tob expire at: 2024-08-11 16:10:26\n", - " - Token: l55****5ol expire at: 2024-07-26 20:30:30\n", - " - Token: 9q2****l33 expire at: 2024-07-28 00:07:03\n", - " - Token: 8b0****ma1 expire at: 2024-08-11 15:25:00\n", - " - Token: oqd****gb7 expire at: 2024-07-26 20:41:53\n", - " - Token: rm2****aj6 expire at: 2024-07-31 17:44:38\n", - " - Token: gfu****iqd expire at: 2024-07-26 04:59:24\n", - " - Token: otr****0f9 expire at: 2024-07-25 22:42:23\n", - " - Token: pj7****j47 expire at: 2024-07-25 20:11:10\n", - " - Token: v2n****j6p expire at: 2024-07-27 11:01:55\n", - " - Token: tsb****74l expire at: 2024-07-28 15:17:29\n", - " - Token: 539****tmn expire at: 2024-07-28 19:23:25\n", - " - Token: 6r1****1u5 expire at: 2024-07-31 17:47:10\n", - " - Token: iun****fos expire at: 2024-07-28 17:18:54\n", - " - Token: ngv****7gu expire at: 2024-08-03 16:39:07\n", - " - Token: nf8****ic6 expire at: 2024-07-26 21:03:13\n", - " - Token: pli****uqa expire at: 2024-07-27 20:50:00\n", - " - Token: 12n****8gh expire at: 2024-07-21 16:42:15\n", - " - Token: ek9****ps9 expire at: 2024-07-31 17:28:46\n", - " - Token: t1f****k7i expire at: 2024-07-28 00:10:28\n", - " - Token: vk2****629 expire at: 2024-07-26 19:17:08\n", - " - Token: tev****3pd expire at: 2024-07-26 14:29:45\n", - " - Token: o4f****899 expire at: 2024-07-26 00:08:24\n", - " - Token: s82****fei expire at: 2024-07-21 16:15:29\n", - " - Token: rvr****350 expire at: 2024-07-25 22:08:48\n", - " - Token: t21****q84 expire at: 2024-07-21 16:13:53\n", - " - Token: qsk****22j expire at: 2024-07-28 16:17:11\n", - " - Token: 2c0****vtp expire at: 2024-07-26 14:06:50\n", - " - Token: 5v6****rcq expire at: 2024-07-26 21:01:56\n", - " - Token: jdm****qlb expire at: 2024-07-26 00:29:56\n", - " - Token: fe9****jtq expire at: 2024-07-31 17:39:01\n", - " - Token: ogl****th2 expire at: 2024-07-25 20:55:50\n", - " - Token: ar9****glu expire at: 2024-07-24 18:45:06\n", - " - Token: fi5****t3t expire at: 2024-07-26 21:02:02\n", - " - Token: pu8****1gu expire at: 2024-07-28 17:20:01\n", - " - Token: v0j****2c0 expire at: 2024-07-28 13:57:02\n", - " - Token: ttl****4pf expire at: 2024-07-24 16:49:27\n", - " - Token: d0t****b91 expire at: 2024-07-27 11:07:12\n", - " - Token: 3i7****scr expire at: 2024-07-28 11:16:03\n", - " - Token: 552****qlb expire at: 2024-08-03 17:35:51\n", - " - Token: h21****lqr expire at: 2024-07-25 22:47:37\n", - " - Token: 2e5****oll expire at: 2024-07-25 20:58:43\n", - " - Token: ggs****c3i expire at: 2024-07-25 22:07:29\n", - " - Token: cm0****m9p expire at: 2024-07-27 18:10:22\n", - " - Token: 8ur****thj expire at: 2024-07-31 17:10:27\n", - " - Token: nfr****8qu expire at: 2024-07-25 20:00:54\n", - " - Token: mt4****s9c expire at: 2024-07-26 13:35:14\n", - " - Token: tvc****kbq expire at: 2024-07-26 17:01:04\n", - " - Token: sbj****dlq expire at: 2024-07-26 00:06:33\n", - " - Token: sek****bcb expire at: 2024-08-03 16:02:51\n", - " - Token: ns4****njt expire at: 2024-07-25 22:43:53\n", - " - Token: eua****g1e expire at: 2024-07-28 17:19:18\n", - " - Token: 1fn****lc4 expire at: 2024-07-28 03:46:01\n", - " - Alias: AUTO_GENERATED_ALIAS_r4tqddc\n", - " - GraphName: Transaction_Fraud\n", - " - Secret: p65****3e4\n", - " - Token: f80****gdi expire at: 2024-08-11 18:20:22\n", - " - Alias: AUTO_GENERATED_ALIAS_p7mnb5e\n", - " - GraphName: TigerGraphRAG\n", - " - Secret: icf****nu0\n", - " - Token: 6ui****mb1 expire at: 2024-08-04 16:03:00\n", - " - Token: k3i****89q expire at: 2024-08-04 16:04:07\n", - " - Token: e6d****n3m expire at: 2024-07-28 17:45:08\n", - " - Token: 4d4****ubm expire at: 2024-07-28 17:45:25\n", - " - Token: e30****qam expire at: 2024-07-24 16:49:01\n", - " - Alias: AUTO_GENERATED_ALIAS_0ijfsnu\n", - " - GraphName: MyGraph\n", - " - Secret: ibm****i7f\n", - " - Token: oru****ucg expire at: 2024-08-15 02:05:49\n", - " - Token: 1ip****rg9 expire at: 2024-08-11 18:27:47\n", - " - Token: 1tg****qp0 expire at: 2024-08-15 02:03:27\n", - " - Token: h34****21t expire at: 2024-07-28 16:41:56\n", - " - Token: 418****iht expire at: 2024-08-10 21:35:24\n", - " - Token: om1****g7q expire at: 2024-08-03 19:49:39\n", - " - Token: dku****9so expire at: 2024-08-10 13:21:12\n", - " - Token: f88****be3 expire at: 2024-08-15 02:11:49\n", - " - Token: vhr****g7m expire at: 2024-08-11 18:30:03\n", - " - Token: qv8****qmb expire at: 2024-07-28 14:29:23\n", - " - Token: mfn****vvb expire at: 2024-07-28 14:44:37\n", - " - Token: ji2****mla expire at: 2024-08-04 15:57:47\n", - " - Token: 2vn****bmt expire at: 2024-08-10 21:08:51\n", - " - Token: fse****gm4 expire at: 2024-08-10 17:40:11\n", - " - Token: 0m1****cc4 expire at: 2024-08-09 21:27:39\n", - " - Token: cp0****d2s expire at: 2024-08-13 23:26:47\n", - " - Token: 9k2****99g expire at: 2024-08-04 15:09:21\n", - " - Token: 3db****gpe expire at: 2024-08-14 20:54:23\n", - " - Token: t8g****31s expire at: 2024-08-14 22:00:17\n", - " - Token: lia****0mu expire at: 2024-07-28 14:27:15\n", - " - Token: k1k****ubc expire at: 2024-07-28 17:00:50\n", - " - Token: d5p****d15 expire at: 2024-08-04 15:48:02\n", - " - Token: 3il****j1n expire at: 2024-08-14 20:52:49\n", - " - Token: de1****i4p expire at: 2024-08-11 17:09:11\n", - " - Token: ppa****5c1 expire at: 2024-08-11 20:14:44\n", - " - Token: v9h****ckd expire at: 2024-08-14 22:05:35\n", - " - Token: 6nn****h1k expire at: 2024-08-03 19:01:00\n", - " - Token: 6hg****0dd expire at: 2024-08-14 22:03:18\n", - " - Token: um0****pbc expire at: 2024-08-10 14:46:47\n", - " - Token: kk6****6dq expire at: 2024-08-05 03:01:07\n", - " - Token: s5u****4ih expire at: 2024-08-11 17:00:04\n", - " - Token: 3lf****qis expire at: 2024-08-10 13:22:07\n", - " - Token: mqf****qp8 expire at: 2024-08-03 19:38:25\n", - " - Token: l24****fja expire at: 2024-08-10 19:34:20\n", - " - Token: vnd****uri expire at: 2024-08-15 02:10:49\n", - " - Token: r9n****59h expire at: 2024-08-11 18:01:05\n", - " - Token: vh1****bg8 expire at: 2024-08-10 14:48:19\n", - " - Token: 4jo****kar expire at: 2024-08-11 20:45:09\n", - " - Token: mod****spb expire at: 2024-08-03 17:54:18\n", - " - Token: mls****kh1 expire at: 2024-08-10 16:01:23\n", - " - Token: e3r****8dh expire at: 2024-07-28 14:23:45\n", - " - Token: 4nc****5h3 expire at: 2024-08-10 14:48:22\n", - " - Token: 49u****1qk expire at: 2024-08-14 20:45:29\n", - " - Token: s92****iej expire at: 2024-07-28 16:32:01\n", - " - Token: fkr****hmn expire at: 2024-07-25 16:31:22\n", - " - Token: pd8****3ab expire at: 2024-08-03 16:46:47\n", - " - Token: o1g****2cd expire at: 2024-07-28 17:02:49\n", - " - Token: 79u****nvi expire at: 2024-08-10 21:52:23\n", - " - Token: ca0****37i expire at: 2024-07-28 16:38:32\n", - " - Token: g9t****h10 expire at: 2024-08-10 21:37:50\n", - " - Token: 5u7****uhn expire at: 2024-08-11 21:06:18\n", - " - Token: nq5****fbc expire at: 2024-07-25 15:16:53\n", - " - Token: ttc****gm7 expire at: 2024-08-03 17:55:09\n", - " - Token: k18****3cs expire at: 2024-08-10 21:07:50\n", - " - Token: 8ci****251 expire at: 2024-08-11 21:03:47\n", - " - Token: pcn****mqk expire at: 2024-08-10 14:54:44\n", - " - Token: 71r****o9p expire at: 2024-08-11 18:24:31\n", - " - Token: t8c****4ns expire at: 2024-07-28 16:38:56\n", - " - Token: ta0****498 expire at: 2024-08-09 21:05:25\n", - " - Token: 2os****vcq expire at: 2024-07-25 15:59:10\n", - " - Token: nfv****avu expire at: 2024-08-11 16:40:54\n", - " - Token: t09****r31 expire at: 2024-07-28 16:55:35\n", - " - Token: lc3****gi7 expire at: 2024-08-10 13:21:43\n", - " - Token: bbe****h49 expire at: 2024-07-25 15:10:42\n", - " - Token: phr****a22 expire at: 2024-08-14 22:05:40\n", - " - Token: eo8****kjh expire at: 2024-08-13 23:32:18\n", - " - Token: u54****rvb expire at: 2024-08-10 17:38:29\n", - " - Token: mb9****1bi expire at: 2024-08-04 17:56:00\n", - " - Token: mjn****9no expire at: 2024-08-09 20:46:47\n", - " - Token: 139****jjn expire at: 2024-07-28 14:46:27\n", - " - Token: 2m7****sp6 expire at: 2024-07-28 16:58:09\n", - " - Token: pit****oln expire at: 2024-07-28 17:01:38\n", - " - Token: 4mn****aa8 expire at: 2024-08-10 19:09:43\n", - " - Token: p08****0nm expire at: 2024-08-14 20:55:50\n", - " - Token: jj7****v0i expire at: 2024-08-02 19:16:02\n", - " - Token: 3s0****1lu expire at: 2024-08-03 10:59:40\n", - " - Token: 495****cvg expire at: 2024-07-28 17:49:47\n", - " - Token: 0ue****nep expire at: 2024-08-04 15:58:52\n", - " - Token: hhf****u5p expire at: 2024-08-11 17:09:21\n", - " - Token: c0q****vs3 expire at: 2024-08-11 17:02:42\n", - " - Token: hnt****tou expire at: 2024-08-11 20:40:15\n", - " - Token: qpq****qsb expire at: 2024-08-03 17:42:40\n", - " - Token: f66****vgs expire at: 2024-08-10 14:46:32\n", - " - Alias: AUTO_GENERATED_ALIAS_9gqutst\n", - " - GraphName: pyTigerGraphRAG\n", - " - LastSuccessLogin: Tue Jul 16 17:02:06 UTC 2024\n", - " - NextValidLogin: Tue Jul 16 17:02:06 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: dgarrigan\n", - " - LastSuccessLogin: Thu May 09 21:02:53 UTC 2024\n", - " - NextValidLogin: Thu May 09 21:02:53 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: user_1\n", - " - LastSuccessLogin: Fri Jun 14 18:04:17 UTC 2024\n", - " - NextValidLogin: Fri Jun 14 18:04:17 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: supawish.limprasert@tigergraph.com\n", - " - Global Roles: superuser\n", - " - Secret: j0t****7cv\n", - " - Alias: AUTO_GENERATED_ALIAS_r6kllut\n", - " - GraphName: Transaction_Fraud\n", - " - Secret: dou****sk7\n", - " - Alias: AUTO_GENERATED_ALIAS_ts7fee2\n", - " - GraphName: MyGraph\n", - " - LastSuccessLogin: Tue May 21 19:20:36 UTC 2024\n", - " - NextValidLogin: Tue May 21 19:20:36 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: victor.moey@tigergraph.com\n", - " - Global Roles: superuser\n", - " - Secret: d3h****394\n", - " - Alias: AUTO_GENERATED_ALIAS_r789a33\n", - " - GraphName: Transaction_Fraud\n", - " - Secret: 4ju****j60\n", - " - Alias: AUTO_GENERATED_ALIAS_fu6kd9p\n", - " - GraphName: MyGraph\n", - " - LastSuccessLogin: Fri May 31 20:22:12 UTC 2024\n", - " - NextValidLogin: Fri May 31 20:22:12 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: arshdeep.kaur@tigergraph.com\n", - " - Global Roles: superuser\n", - " - Secret: u6l****nmr\n", - " - Alias: AUTO_GENERATED_ALIAS_7q0hkpb\n", - " - GraphName: MyGraph\n", - " - LastSuccessLogin: Mon Jun 03 18:44:47 UTC 2024\n", - " - NextValidLogin: Mon Jun 03 18:44:47 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: lu.zhou@tigergraph.com\n", - " - Global Roles: superuser\n", - " - Secret: va0****b0s\n", - " - Token: 0ns****vuo expire at: 2024-07-18 16:20:54\n", - " - Token: jrh****pcv expire at: 2024-07-18 16:20:54\n", - " - Token: vag****t2d expire at: 2024-07-18 22:00:50\n", - " - Token: kgd****qej expire at: 2024-07-21 05:35:17\n", - " - Token: 4po****p18 expire at: 2024-07-24 19:48:08\n", - " - Token: oog****dbo expire at: 2024-07-19 17:06:19\n", - " - Token: o9l****sa2 expire at: 2024-07-19 06:13:58\n", - " - Token: itd****03k expire at: 2024-07-20 16:17:20\n", - " - Alias: AUTO_GENERATED_ALIAS_so4sd2c\n", - " - GraphName: Transaction_Fraud\n", - " - Secret: p9q****ifd\n", - " - Token: sp0****h0i expire at: 2024-07-18 22:00:44\n", - " - Token: 13b****8am expire at: 2024-08-09 19:37:09\n", - " - Token: rld****92k expire at: 2024-07-24 19:47:54\n", - " - Alias: AUTO_GENERATED_ALIAS_2a0lmf0\n", - " - GraphName: MyGraph\n", - " - LastSuccessLogin: Fri Jun 14 15:56:48 UTC 2024\n", - " - NextValidLogin: Fri Jun 14 15:56:48 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n", - " - Name: user_2\n", - " - Global Roles: superuser\n", - " - Graph 'Transaction_Fraud' Roles: admin\n", - " - Secret: 4re****k8d\n", - " - Token: l86****9pd expire at: 2024-07-19 15:07:25\n", - " - Token: hss****8hc expire at: 2024-07-19 15:18:01\n", - " - Token: 74f****0rg expire at: 2024-07-19 21:02:23\n", - " - Token: g3s****fiq expire at: 2024-07-18 21:08:00\n", - " - Token: 45c****e5j expire at: 2024-07-19 15:19:23\n", - " - Token: kk3****j58 expire at: 2024-07-19 14:33:50\n", - " - Token: gpa****ebi expire at: 2024-07-19 21:11:50\n", - " - Token: i3h****b18 expire at: 2024-07-19 14:32:33\n", - " - Token: 27q****kel expire at: 2024-07-19 14:46:03\n", - " - Token: jlb****ak2 expire at: 2024-07-19 15:24:57\n", - " - Token: hlj****kk5 expire at: 2024-07-19 19:35:58\n", - " - Token: r8l****r52 expire at: 2024-07-17 15:29:38\n", - " - Token: 6h8****35q expire at: 2024-07-20 15:25:50\n", - " - Token: 3sm****d5c expire at: 2024-07-18 21:18:31\n", - " - Token: 08p****dv9 expire at: 2024-07-18 21:07:34\n", - " - Token: 0mj****f4d expire at: 2024-07-17 15:29:38\n", - " - Token: r8u****i78 expire at: 2024-07-19 21:16:36\n", - " - Token: j26****p6q expire at: 2024-07-19 15:12:28\n", - " - Token: e3c****ht2 expire at: 2024-07-18 21:12:48\n", - " - Token: 2j0****g1v expire at: 2024-07-19 14:34:46\n", - " - Token: 9eo****th2 expire at: 2024-07-19 14:43:40\n", - " - Token: spr****0rs expire at: 2024-07-19 15:15:49\n", - " - Token: csb****e80 expire at: 2024-07-18 23:15:18\n", - " - Token: uku****90d expire at: 2024-07-19 14:37:01\n", - " - Token: p53****cav expire at: 2024-07-19 15:20:46\n", - " - Token: 414****rdh expire at: 2024-07-20 15:27:02\n", - " - Token: rv9****fjv expire at: 2024-07-19 21:06:57\n", - " - Token: mqd****grf expire at: 2024-07-19 14:49:09\n", - " - Token: fdu****kln expire at: 2024-07-18 21:10:31\n", - " - Token: 1dm****kma expire at: 2024-07-18 21:16:21\n", - " - Token: 2cq****80i expire at: 2024-07-20 15:26:13\n", - " - Token: h5b****4ap expire at: 2024-07-25 22:14:59\n", - " - Token: qis****4op expire at: 2024-07-20 15:26:38\n", - " - Alias: AUTO_GENERATED_ALIAS_02uaop4\n", - " - GraphName: Transaction_Fraud\n", - " - Secret: ecb****fce\n", - " - Token: p6b****kp9 expire at: 2024-07-26 13:26:53\n", - " - Token: 3a1****a5p expire at: 2024-07-25 21:49:27\n", - " - Alias: AUTO_GENERATED_ALIAS_4fcktc1\n", - " - GraphName: TigerGraphRAG\n", - " - Secret: ds5****gri\n", - " - Token: h6j****ajg expire at: 2024-07-18 13:17:19\n", - " - Token: bj2****qun expire at: 2024-07-17 21:24:51\n", - " - Token: o4s****94j expire at: 2024-08-11 13:00:04\n", - " - Token: k98****5ca expire at: 2024-07-17 21:24:26\n", - " - Token: 4s1****jlv expire at: 2024-07-18 00:43:29\n", - " - Token: t5u****71u expire at: 2024-07-25 13:01:56\n", - " - Token: ji4****3bs expire at: 2024-07-24 21:01:52\n", - " - Alias: AUTO_GENERATED_ALIAS_29i5m13\n", - " - GraphName: MyGraph\n", - " - Secret: 1oh****3p8\n", - " - Token: 7og****rtq expire at: 2024-07-27 05:27:53\n", - " - Token: gmk****fvs expire at: 2024-07-27 05:27:56\n", - " - Token: r94****t7m expire at: 2024-07-27 05:27:57\n", - " - Token: rdr****8iv expire at: 2024-07-25 16:37:12\n", - " - Token: 0ab****pro expire at: 2024-07-27 05:27:55\n", - " - Token: ql0****s8d expire at: 2024-07-26 17:37:06\n", - " - Token: 87e****d2s expire at: 2024-07-27 05:27:54\n", - " - Token: md3****mp8 expire at: 2024-07-25 13:08:26\n", - " - Token: 4fh****e46 expire at: 2024-07-27 12:59:08\n", - " - Token: j10****s4b expire at: 2024-07-26 13:46:49\n", - " - Token: qf1****05n expire at: 2024-07-27 13:31:41\n", - " - Token: ubj****ukd expire at: 2024-07-27 14:11:31\n", - " - Token: 6vl****3lb expire at: 2024-07-27 05:14:49\n", - " - Token: 5gq****qvb expire at: 2024-07-27 05:27:57\n", - " - Token: u32****0r5 expire at: 2024-07-27 13:22:04\n", - " - Token: s7d****ndh expire at: 2024-07-27 13:02:25\n", - " - Token: ek8****oil expire at: 2024-07-27 13:53:52\n", - " - Token: hev****e26 expire at: 2024-07-25 20:56:29\n", - " - Token: j8v****32g expire at: 2024-07-26 13:47:00\n", - " - Token: p08****vib expire at: 2024-07-27 13:34:32\n", - " - Token: jfd****orj expire at: 2024-07-27 05:27:54\n", - " - Token: bmh****b23 expire at: 2024-07-27 13:51:15\n", - " - Token: doe****21f expire at: 2024-07-25 16:16:48\n", - " - Token: bjq****2lm expire at: 2024-07-27 05:27:56\n", - " - Token: fba****fds expire at: 2024-07-27 13:26:42\n", - " - Token: iqh****8sc expire at: 2024-07-27 05:27:55\n", - " - Token: gm7****f4u expire at: 2024-07-27 05:18:22\n", - " - Token: c7b****2fg expire at: 2024-07-27 13:27:54\n", - " - Token: f4v****btu expire at: 2024-07-27 14:18:54\n", - " - Token: tjd****00b expire at: 2024-07-27 05:27:54\n", - " - Token: bif****90h expire at: 2024-07-27 13:25:00\n", - " - Token: d44****98l expire at: 2024-07-27 13:18:26\n", - " - Alias: AUTO_GENERATED_ALIAS_ohpig6e\n", - " - GraphName: pyTigerGraphRAG\n", - " - LastSuccessLogin: Tue Jul 02 21:26:28 UTC 2024\n", - " - NextValidLogin: Tue Jul 02 21:26:28 UTC 2024\n", - " - FailedAttempts: 0\n", - " - ShowAlterPasswordWarning: false\n", - "\n" - ] - }, - { - "data": { - "text/plain": [ - "({'tigergraph': 'superuser',\n", - " 'parker.erickson@tigergraph.com': 'superuser',\n", - " 'zhixian.yan@tigergraph.com': 'superuser',\n", - " 'duc.hoai.le@tigergraph.com': 'superuser',\n", - " 'douglas.garrigan@tigergraph.com': 'superuser',\n", - " 'wyatt.joyner@tigergraph.com': 'superuser',\n", - " 'carl.boudreau@tigergraph.com': 'superuser',\n", - " 'alexander.thomas@tigergraph.com': 'superuser',\n", - " 'robert.rossmiller@tigergraph.com': 'superuser',\n", - " 'bill.shi@tigergraph.com': 'superuser',\n", - " 'yuling.liu@tigergraph.com': 'superuser',\n", - " 'kevin.stone@tigergraph.com': 'superuser',\n", - " 'supportai': 'superuser',\n", - " 'supawish.limprasert@tigergraph.com': 'superuser',\n", - " 'victor.moey@tigergraph.com': 'superuser',\n", - " 'arshdeep.kaur@tigergraph.com': 'superuser',\n", - " 'lu.zhou@tigergraph.com': 'superuser',\n", - " 'user_2': 'superuser'},\n", - " )" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "import re\n", + "import requests\n", + "import json\n", + "import base64\n", "\n", "from fastapi import HTTPException, status\n", "from pyTigerGraph import TigerGraphConnection\n", "# from app.common.config import db_config\n", "\n", + "# Define roles with full access\n", + "ALLOWED_ROLES = {'superuser', 'globaldesigner', 'admin'}\n", + "\n", "user_role_pattern = r'- Name:\\s+(.+?)\\s+- Global Roles:\\s+(.+?)\\s+-'\n", "\n", - "def auth(username: str, password: str, conn=None) -> tuple[list[str], TigerGraphConnection]:\n", + "def get_user_role(username: str, password: str, conn=None) -> tuple[list[str], TigerGraphConnection]:\n", " if conn is None:\n", " conn = TigerGraphConnection(\n", " # host=db_config[\"hostname\"], graphname=\"\", username=username, password=password\n", - " host=\"https://tg-26bfd0cd-6582-414e-937e-e2c83ecb5a79.us-east-1.i.tgcloud.io\",\n", + " host=\"tigergraph_host\",\n", " graphname=\"\", username=username, password=password\n", " )\n", "\n", @@ -968,7 +32,7 @@ " # parse user info\n", " info = conn.gsql(\"SHOW USER\")\n", " user_roles = {}\n", - " print (info)\n", + " # print (info)\n", " for match in re.finditer(user_role_pattern, info):\n", " name = match.group(1).strip()\n", " global_roles = match.group(2).strip()\n", @@ -981,633 +45,379 @@ " )\n", " except Exception as e:\n", " raise e\n", - " return user_roles, conn\n", + " return user_roles, conn" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "user_roles, conn = get_user_role(username=\"USERNAME\", password=\"PASSWORD\")\n", "\n", - "auth(username=\"supportai\", password=\"supportai\")" + "for user, roles in user_roles.items():\n", + " print (f\"{user}: {roles}\")" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[\n", - " {\n", - " \"id\": 1,\n", - " \"create_ts\": \"2024-07-12T01:09:30.941010925Z\",\n", - " \"update_ts\": \"2024-07-12T01:09:30.941010925Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"5778f874-62e0-496b-a778-45a2a64ce4d0\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 2,\n", - " \"create_ts\": \"2024-07-12T01:13:33.506768718Z\",\n", - " \"update_ts\": \"2024-07-12T01:13:33.506768718Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"e31a8429-6b63-4777-ad68-f7ba06965eab\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 3,\n", - " \"create_ts\": \"2024-07-12T01:19:14.201770208Z\",\n", - " \"update_ts\": \"2024-07-12T01:19:14.201770208Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"8efe1d50-ed65-4e63-a3e7-b0470248d6e4\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 4,\n", - " \"create_ts\": \"2024-07-12T01:22:22.141025337Z\",\n", - " \"update_ts\": \"2024-07-12T01:22:22.141025337Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"051bb4d7-1e74-4e3e-90ae-8798d095cca6\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 5,\n", - " \"create_ts\": \"2024-07-12T03:37:53.87003471Z\",\n", - " \"update_ts\": \"2024-07-12T03:37:53.87003471Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"0475e8af-684b-4e5d-8ea9-ec074044d6f3\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 6,\n", - " \"create_ts\": \"2024-07-12T03:48:25.821287804Z\",\n", - " \"update_ts\": \"2024-07-12T03:48:25.821287804Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"27cbc602-cdc6-4805-bd81-faa63a7b165a\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 7,\n", - " \"create_ts\": \"2024-07-12T05:04:43.126749756Z\",\n", - " \"update_ts\": \"2024-07-12T05:04:43.126749756Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"c153b4be-d69e-43a3-b474-a15de40eb2c3\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 8,\n", - " \"create_ts\": \"2024-07-12T05:08:21.196420552Z\",\n", - " \"update_ts\": \"2024-07-12T05:08:21.196420552Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"6e05c4b1-6221-448f-8535-597fae556359\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 9,\n", - " \"create_ts\": \"2024-07-12T05:12:21.556408385Z\",\n", - " \"update_ts\": \"2024-07-12T05:12:21.556408385Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"e48f4c87-7427-4878-aeb8-a88a53210dfd\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 10,\n", - " \"create_ts\": \"2024-07-12T05:31:51.453909135Z\",\n", - " \"update_ts\": \"2024-07-12T05:31:51.453909135Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"dfde08fd-6c2d-4298-9f3d-ef1d382bbd95\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 11,\n", - " \"create_ts\": \"2024-07-12T05:35:48.387888759Z\",\n", - " \"update_ts\": \"2024-07-12T05:35:48.387888759Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"3984fe5f-45ae-4235-b22c-1963b1264077\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 12,\n", - " \"create_ts\": \"2024-07-12T05:44:22.915609052Z\",\n", - " \"update_ts\": \"2024-07-12T05:44:22.915609052Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"1db57ddb-0822-4d78-b21e-071955f0be7c\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 13,\n", - " \"create_ts\": \"2024-07-12T06:03:25.05808772Z\",\n", - " \"update_ts\": \"2024-07-12T06:03:25.05808772Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"6b892de8-8829-419a-9338-a4645bf8975d\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 14,\n", - " \"create_ts\": \"2024-07-12T06:07:44.474187757Z\",\n", - " \"update_ts\": \"2024-07-12T06:07:44.474187757Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"2581b958-afe1-40b8-9cbb-b344529d700e\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 15,\n", - " \"create_ts\": \"2024-07-12T06:17:15.128616757Z\",\n", - " \"update_ts\": \"2024-07-12T06:17:15.128616757Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"01923556-2957-44de-b2ba-608cbed239c8\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 16,\n", - " \"create_ts\": \"2024-07-12T06:24:59.34439018Z\",\n", - " \"update_ts\": \"2024-07-12T06:24:59.34439018Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"4a3763be-d84a-4fdd-ab9b-460c8025e03f\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 17,\n", - " \"create_ts\": \"2024-07-12T06:39:27.167549429Z\",\n", - " \"update_ts\": \"2024-07-12T06:39:27.167549429Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"91b7d06f-8e89-412d-a685-19071b13bfd2\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 18,\n", - " \"create_ts\": \"2024-07-12T06:41:30.811833792Z\",\n", - " \"update_ts\": \"2024-07-12T06:41:30.811833792Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"ec747115-ffe2-44cb-84bd-77fe966d828f\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 19,\n", - " \"create_ts\": \"2024-07-12T06:43:20.531792176Z\",\n", - " \"update_ts\": \"2024-07-12T06:43:20.531792176Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"f80cdd2a-89dc-4005-9494-a0f069a0e3c9\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 20,\n", - " \"create_ts\": \"2024-07-12T07:06:03.410195418Z\",\n", - " \"update_ts\": \"2024-07-12T07:06:03.410195418Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"81f3e1d7-b0b9-4492-ba64-a1c3a39d9840\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 21,\n", - " \"create_ts\": \"2024-07-12T07:31:58.792245971Z\",\n", - " \"update_ts\": \"2024-07-12T07:31:58.792245971Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"3c25a527-eb46-4a56-bc9d-705492fbedbc\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 22,\n", - " \"create_ts\": \"2024-07-12T08:06:04.311149305Z\",\n", - " \"update_ts\": \"2024-07-12T08:06:04.311149305Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"9d10b5cb-90a3-46ac-afab-0e8214a9def9\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 23,\n", - " \"create_ts\": \"2024-07-12T08:18:41.28110421Z\",\n", - " \"update_ts\": \"2024-07-12T08:18:41.28110421Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"7661baab-7ae4-4db4-a85d-fcc456590d87\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 24,\n", - " \"create_ts\": \"2024-07-12T08:22:01.357121887Z\",\n", - " \"update_ts\": \"2024-07-12T08:22:01.357121887Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"ba0518a6-b176-438a-a550-6b388dc25c14\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 25,\n", - " \"create_ts\": \"2024-07-12T08:23:57.618055093Z\",\n", - " \"update_ts\": \"2024-07-12T08:23:57.618055093Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"eaea7cf7-de32-484a-bcf7-a50f2e49ec99\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 26,\n", - " \"create_ts\": \"2024-07-12T08:29:16.947943005Z\",\n", - " \"update_ts\": \"2024-07-12T08:29:16.947943005Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"b063d493-e925-4c60-91fd-ce81080b02d7\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 27,\n", - " \"create_ts\": \"2024-07-12T08:54:38.647550709Z\",\n", - " \"update_ts\": \"2024-07-12T08:54:38.647550709Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"980e2438-11ba-4b1f-b77b-7276d855557b\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 28,\n", - " \"create_ts\": \"2024-07-12T09:04:17.060111255Z\",\n", - " \"update_ts\": \"2024-07-12T09:04:17.060111255Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"b5853229-d770-4103-b944-888deb8af1bd\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 29,\n", - " \"create_ts\": \"2024-07-12T09:17:17.643967922Z\",\n", - " \"update_ts\": \"2024-07-12T09:17:17.643967922Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"6f900ce2-e9d8-41ee-92ad-b337c4a71a8d\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 30,\n", - " \"create_ts\": \"2024-07-12T09:19:44.777980004Z\",\n", - " \"update_ts\": \"2024-07-12T09:19:44.777980004Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"532da9cb-0587-466f-b180-569144b8e5ad\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 31,\n", - " \"create_ts\": \"2024-07-12T15:47:41.095163511Z\",\n", - " \"update_ts\": \"2024-07-12T15:47:41.095163511Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"44750bd3-78a6-4f6e-b6de-1b3faeddfa2d\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 32,\n", - " \"create_ts\": \"2024-07-12T15:50:34.102892466Z\",\n", - " \"update_ts\": \"2024-07-12T15:50:34.102892466Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"212be4b5-e59b-48a7-bb2c-2ad59e4661a4\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 33,\n", - " \"create_ts\": \"2024-07-12T16:15:56.12926367Z\",\n", - " \"update_ts\": \"2024-07-12T16:15:56.12926367Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"3c628375-0b22-41d1-b231-87b4b7cc9eac\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 34,\n", - " \"create_ts\": \"2024-07-12T16:29:52.033069335Z\",\n", - " \"update_ts\": \"2024-07-12T16:29:52.033069335Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"ee6322c2-4916-4590-b592-df01cdce9054\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 35,\n", - " \"create_ts\": \"2024-07-12T16:42:21.648080543Z\",\n", - " \"update_ts\": \"2024-07-12T16:42:21.648080543Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"56a5138d-d4e5-493c-bcb2-35371e171dd0\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 36,\n", - " \"create_ts\": \"2024-07-12T16:49:12.511050886Z\",\n", - " \"update_ts\": \"2024-07-12T16:49:12.511050886Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"1f54367e-f481-4fda-b70b-c7c1cd1c2108\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 37,\n", - " \"create_ts\": \"2024-07-12T16:55:14.639173596Z\",\n", - " \"update_ts\": \"2024-07-12T16:55:14.639173596Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"fd125c22-2d5b-448b-9700-08073a74dff3\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 38,\n", - " \"create_ts\": \"2024-07-12T16:57:43.635279762Z\",\n", - " \"update_ts\": \"2024-07-12T16:57:43.635279762Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"40206d11-911f-4a8a-a90e-ecb78e8a076a\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 39,\n", - " \"create_ts\": \"2024-07-12T17:07:49.483211375Z\",\n", - " \"update_ts\": \"2024-07-12T17:07:49.483211375Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"e2795df0-2f29-4ce0-b56f-c5d6b58263e6\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 40,\n", - " \"create_ts\": \"2024-07-12T17:18:13.83835222Z\",\n", - " \"update_ts\": \"2024-07-12T17:18:13.83835222Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"d564c44d-4f96-4d0a-9c47-63bc97833664\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 41,\n", - " \"create_ts\": \"2024-07-12T17:35:06.945250967Z\",\n", - " \"update_ts\": \"2024-07-12T17:35:06.945250967Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"94a2456b-5e71-40d9-a145-9aa16a4ea964\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 42,\n", - " \"create_ts\": \"2024-07-12T17:40:02.980941548Z\",\n", - " \"update_ts\": \"2024-07-12T17:40:02.980941548Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"fe8c714a-9808-4d7b-8db7-d45bc9289776\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 43,\n", - " \"create_ts\": \"2024-07-12T17:43:59.425786005Z\",\n", - " \"update_ts\": \"2024-07-12T17:43:59.425786005Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"b1c23ed1-26e5-4f15-8eee-1092cec14458\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 44,\n", - " \"create_ts\": \"2024-07-12T17:46:13.640628803Z\",\n", - " \"update_ts\": \"2024-07-12T17:46:13.640628803Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"f6619dbb-777b-4c49-8719-a3dd7fa252d8\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 45,\n", - " \"create_ts\": \"2024-07-12T17:54:45.588624429Z\",\n", - " \"update_ts\": \"2024-07-12T17:54:45.588624429Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"01708f67-e553-43e4-b5cd-489a32c31f72\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 46,\n", - " \"create_ts\": \"2024-07-12T19:58:11.22233526Z\",\n", - " \"update_ts\": \"2024-07-12T19:58:11.22233526Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"a8cc1d9e-b01c-4c7b-bb7d-5284ea0038fa\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 47,\n", - " \"create_ts\": \"2024-07-12T21:04:29.768814424Z\",\n", - " \"update_ts\": \"2024-07-12T21:04:29.768814424Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"4d745509-3ab3-408a-a4a1-596cb7f56717\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 48,\n", - " \"create_ts\": \"2024-07-13T05:45:00.694247342Z\",\n", - " \"update_ts\": \"2024-07-13T05:45:00.694247342Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"676e1c45-3d82-40cf-8f78-b8c646c0169b\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 49,\n", - " \"create_ts\": \"2024-07-13T06:05:02.275046176Z\",\n", - " \"update_ts\": \"2024-07-13T06:05:02.275046176Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"84d93e14-2cfa-405d-8f9e-65d697812be9\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 50,\n", - " \"create_ts\": \"2024-07-13T06:15:00.605215383Z\",\n", - " \"update_ts\": \"2024-07-13T06:15:00.605215383Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"aa91756d-bd93-4d83-bf4a-b9f8439cb326\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 51,\n", - " \"create_ts\": \"2024-07-13T06:29:04.360870469Z\",\n", - " \"update_ts\": \"2024-07-13T06:29:04.360870469Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"240c3c12-544b-4739-a3c0-1c9bb110cb50\",\n", - " \"name\": \"\"\n", - " },\n", - " {\n", - " \"id\": 52,\n", - " \"create_ts\": \"2024-07-15T17:54:32.215517876Z\",\n", - " \"update_ts\": \"2024-07-15T17:54:32.215517876Z\",\n", - " \"delete_ts\": null,\n", - " \"user_id\": \"supportai\",\n", - " \"conversation_id\": \"06b077fe-5199-46fb-93b6-471ed7ae5277\",\n", - " \"name\": \"\"\n", - " }\n", - "]\n" - ] - } - ], + "outputs": [], "source": [ - "import requests\n", - "import json\n", + "def create_headers(username, password):\n", + " \"\"\"Create headers with Base64 encoded credentials.\"\"\"\n", + " credentials = f\"{username}:{password}\"\n", + " encoded_credentials = base64.b64encode(credentials.encode(\"utf-8\")).decode(\"utf-8\")\n", + " return {\n", + " 'accept': 'application/json',\n", + " 'Authorization': f'Basic {encoded_credentials}'\n", + " }" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_user_conversation_ids(username, password):\n", + " \"\"\"Fetch conversation IDs for a given user.\"\"\"\n", + " headers = create_headers(username, password)\n", + " user_url = f'http://0.0.0.0:8000/ui/user/{username}'\n", + " \n", + " response = requests.get(user_url, headers=headers)\n", + " \n", + " if response.status_code == 200:\n", + " data = response.json()\n", + " return [item['conversation_id'] for item in data]\n", + " else:\n", + " print(f\"Request failed with status code {response.status_code}\")\n", + " print(response.text)\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "get_user_conversation_ids(\"supportai\", \"supportai\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_conversation_data(username, password, conversation_id):\n", + " \"\"\"Fetch conversation data for a given conversation ID.\"\"\"\n", + " headers = create_headers(username, password)\n", + " conversation_url = f'http://0.0.0.0:8000/ui/conversation/{conversation_id}'\n", + " \n", + " response = requests.get(conversation_url, headers=headers)\n", + " \n", + " if response.status_code == 200:\n", + " data = response.json()\n", + " # return [\n", + " # {\n", + " # \"id\": message[\"id\"],\n", + " # \"message_id\": message[\"message_id\"],\n", + " # \"parent_id\": message[\"parent_id\"],\n", + " # \"role\": message[\"role\"],\n", + " # \"content\": message.get(\"content\", \"\"),\n", + " # \"feedback\": message.get(\"feedback\", \"\")\n", + " # }\n", + " # for message in data\n", + " # ]\n", + " \n", + " # Create dictionaries to hold user questions and system answers\n", + " questions = {message[\"message_id\"]: message for message in data if message[\"role\"] == \"user\"}\n", + " answers = {message[\"parent_id\"]: message for message in data if message[\"role\"] == \"system\"}\n", + " \n", + " # return questions, answers\n", + " # Organize into Q&A pairs\n", + " qa_pairs = []\n", + " for q_id, question in questions.items():\n", + " if q_id in answers:\n", + " qa_pairs.append({\n", + " \"question\": question[\"content\"],\n", + " \"answer\": answers[q_id][\"content\"],\n", + " \"feedback\": answers[q_id][\"feedback\"]\n", + " })\n", + " \n", + " return qa_pairs\n", + " else:\n", + " print(f\"Request failed with status code {response.status_code}\")\n", + " print(response.text)\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def check_user_role(username, password, user_roles, conversation_id=None):\n", + " \"\"\"Check user role and permissions for accessing conversations.\"\"\"\n", + " if username not in user_roles:\n", + " return \"User does not exist in the database.\"\n", + " \n", + " if user_roles.get(username) in {'superuser', 'globaldesigner', 'admin'}:\n", + " return True # Allow access for superusers, global designers, and admins\n", + " elif conversation_id:\n", + " # For non-superuser roles, check if the conversation belongs to the user\n", + " conversation_ids = get_user_conversation_ids(username, password)\n", + " if conversation_id in conversation_ids:\n", + " return True\n", + " else:\n", + " return False\n", + " else:\n", + " return False" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def fetch_user_conversations(username, password, user_roles, conversation_id=None):\n", + " \"\"\"Fetch conversations based on user roles and permissions.\"\"\"\n", + " permission_check = check_user_role(username, password, user_roles)\n", + " if permission_check is not True:\n", + " return permission_check # Return the error message if permissions are insufficient or user does not exist\n", + "\n", + " if conversation_id:\n", + " # Fetch a specific conversation\n", + " data = get_conversation_data(username, password, conversation_id)\n", + " if data:\n", + " return data\n", + " else:\n", + " return \"Conversation not found or could not be retrieved.\"\n", + " \n", + " else:\n", + " # Fetch all conversations\n", + " conversation_ids = get_user_conversation_ids(username, password)\n", + " conversations = {}\n", + " \n", + " for conv_id in conversation_ids:\n", + " data = get_conversation_data(username, password, conv_id)\n", + " if data:\n", + " conversations[conv_id] = data\n", + " \n", + " return conversations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "conversation_data = fetch_user_conversations(\"USERNAME\", \"PASSWORD\", user_roles, \"CONVO_ID\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_feedback_stats(conversation_data):\n", + " # Initialize counters\n", + " feedback_counts = {'No Feedback': 0, 'Thumbs Up': 0, 'Thumbs Down': 0}\n", + " total_entries = len(conversation_data)\n", + " \n", + " # Count feedback occurrences\n", + " for entry in conversation_data:\n", + " feedback = entry['feedback']\n", + " if feedback == 0:\n", + " feedback_counts['No Feedback'] += 1\n", + " elif feedback == 1:\n", + " feedback_counts['Thumbs Up'] += 1\n", + " elif feedback == 2:\n", + " feedback_counts['Thumbs Down'] += 1\n", + " \n", + " # Calculate percentages\n", + " feedback_percentages = {k: (v / total_entries) * 100 for k, v in feedback_counts.items()}\n", + " \n", + " return feedback_counts, feedback_percentages" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Get feedback stats\n", + "feedback_counts, feedback_percentages = get_feedback_stats(conversation_data)\n", "\n", - "headers = {\n", - " 'accept': 'application/json',\n", - " 'Authorization': 'Basic c3VwcG9ydGFpOnN1cHBvcnRhaQ=='\n", - "}\n", + "print(\"Feedback Counts:\", feedback_counts)\n", + "print(\"Feedback Percentages:\", feedback_percentages)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import openai\n", + "\n", + "# Set your OpenAI API key\n", + "openai.api_key = 'APIKEY'\n", + "\n", + "# def summarize_text(text):\n", + "# response = openai.chat.completions.create(\n", + "# model=\"gpt-4\", \n", + "# messages=[\n", + "# {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n", + "# {\"role\": \"user\", \"content\": f\"Summarize the following text:\\n\\n{text}\"}\n", + "# ],\n", + "# max_tokens=100, # Adjust the number of tokens as needed\n", + "# temperature=0.1\n", + "# )\n", + "# return response.choices[0].message.content.strip()\n", + "\n", + "def classify_text(text, labels):\n", + " response = openai.chat.completions.create(\n", + " model=\"gpt-4\",\n", + " messages = [\n", + " {\"role\": \"system\", \"content\": \"You are an assistant that classifies text into categories.\"},\n", + " {\"role\": \"user\", \"content\": f\"Classify the following text into one of these categories: {', '.join(labels)}\\n\\nText:\\n{text} and just return the labels only\"}\n", + " ],\n", + " max_tokens=50, # Adjust the number of tokens as needed\n", + " temperature=0.1\n", + " )\n", + " return response.choices[0].message.content.strip()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "feedback_messages = [item['question'] for item in conversation_data]\n", + "\n", + "# Define labels for classification\n", + "labels = [\"Missing Information\", \"Incorrect Information\", \"Irrelevant Information\"]\n", + "\n", + "# Process each piece of conversation data\n", + "# for i, text in enumerate(feedback_messages):\n", + "# # summary = summarize_text(text)\n", + "# classification = classify_text(text, labels)\n", + "# # print(f\"Conversation {i+1} Summary: {summary}\")\n", + "# print(f\"Message: {text}\")\n", + "# print(f\"Classification: {classification}\")\n", + "# print(\"---\")\n", "\n", - "user_id = \"supportai\"\n", + "# Print the results in the desired format\n", + "# Initialize a dictionary to store classified issues\n", + "classified_issues = {category: [] for category in labels}\n", "\n", - "user_url = f'http://0.0.0.0:8000/ui/user/{user_id}'\n", + "results = {}\n", "\n", - "response = requests.get(user_url, headers=headers)\n", + "for message in feedback_messages:\n", + " result = classify_text(message, labels)\n", + " results[message] = result\n", + "# Categorize each piece of text\n", + "for text, category in results.items() :\n", + " if category in classified_issues:\n", + " classified_issues[category].append(text)\n", + " else:\n", + " classified_issues['Other'].append(text)\n", "\n", - "if response.status_code == 200:\n", - " data = response.json()\n", - " print(json.dumps(data, indent=2))\n", - "else:\n", - " print(f\"Request failed with status code {response.status_code}\")\n", - " print(response.text) # Print the error message or response content" + "# Print the results in the desired format\n", + "print(\"\\nCategorized Issues:\\n\")\n", + "for category in labels:\n", + " if classified_issues[category]:\n", + " print(f\"{category}:\")\n", + " for issue in classified_issues[category]:\n", + " print(f\" - {issue}\")\n", + " print() # Add a newline for better readability" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[\n", - " {\n", - " \"id\": 273,\n", - " \"content\": \"Find all transactions, from 2/1/21 to 5/1/21 above average amount for that card. Sort the results.\",\n", - " \"feedback\": 0\n", - " },\n", - " {\n", - " \"id\": 274,\n", - " \"content\": \"The transactions from 2/1/21 to 5/1/21 that were above the average amount for that card are as follows: Transaction with id 39843 on 2021-04-17 with amount 7855.36, transaction with id 40831 on 2021-04-24 with amount 2934.13, transaction with id 871054 on 2021-02-02 with amount 5321.52, transaction with id 769 on 2021-04-17 with amount 2802.55, transaction with id 34336 on 2021-04-24 with amount 4935.42, transaction with id 473824 on 2021-04-18 with amount 3713.09, and transaction with id 7815 on 2021-04-17 with amount 6044.24.\",\n", - " \"feedback\": 0\n", - " },\n", - " {\n", - " \"id\": 275,\n", - " \"content\": \"Provide more details about this transaction 871054, like the card used and merchant involved in this transaction.\",\n", - " \"feedback\": 0\n", - " },\n", - " {\n", - " \"id\": 276,\n", - " \"content\": \"The transaction with the ID 871054 was a payment transaction that occurred at the time 2021-02-02 00:00:00. The amount involved in this transaction was 5321.52. The transaction was marked as fraudulent. However, the details about the card used and the merchant involved in this transaction are not provided in the given context.\",\n", - " \"feedback\": 0\n", - " },\n", - " {\n", - " \"id\": 277,\n", - " \"content\": \"what merchant is involved in the transaction 871054?\",\n", - " \"feedback\": 0\n", - " },\n", - " {\n", - " \"id\": 278,\n", - " \"content\": \"The merchant involved in the transaction 871054 is fraud_Kuhn LLC.\",\n", - " \"feedback\": 0\n", - " },\n", - " {\n", - " \"id\": 279,\n", - " \"content\": \"what card is used in the transaction 871054?\",\n", - " \"feedback\": 0\n", - " },\n", - " {\n", - " \"id\": 280,\n", - " \"content\": \"The context does not provide information on what card was used in transaction 871054.\",\n", - " \"feedback\": 0\n", - " },\n", - " {\n", - " \"id\": 281,\n", - " \"content\": \"List all merchants that have more than 2500 transactions from 2021-02-01 to 2021-10-01.\",\n", - " \"feedback\": 0\n", - " },\n", - " {\n", - " \"id\": 282,\n", - " \"content\": \"The merchants that have more than 2500 transactions from 2021-02-01 to 2021-10-01 are Kilback LLC with 2909 transactions and Kuhn LLC with 2610 transactions.\",\n", - " \"feedback\": 0\n", - " }\n", - "]\n" - ] - } - ], + "outputs": [], "source": [ - "conversation_id = \"06b077fe-5199-46fb-93b6-471ed7ae5277\"\n", + "from transformers import pipeline\n", + "from tqdm import tqdm\n", "\n", - "conversation_url = f'http://0.0.0.0:8000/ui/conversation/{conversation_id}'\n", + "# Load summarization and zero-shot classification pipelines\n", + "summarizer = pipeline(\"summarization\", model=\"facebook/bart-large-cnn\")\n", + "classifier = pipeline(\"zero-shot-classification\", model=\"facebook/bart-large-mnli\")\n", "\n", - "response = requests.get(conversation_url, headers=headers)\n", + "def analyze_negative_feedback_with_llm(conversation_data):\n", + " negative_feedback_entries = [entry for entry in conversation_data if entry['feedback'] == 2]\n", + " \n", + " # Define categories for classification\n", + " categories = [\"Missing Information\", \"Incorrect Information\", \"Irrelevant Information\", \"Other\"]\n", + " \n", + " summarized_issues = []\n", + " categorized_issues = {category: [] for category in categories}\n", + " \n", + " for entry in negative_feedback_entries:\n", + " content = entry['content']\n", "\n", - "if response.status_code == 200:\n", - " conversation_data = []\n", - " data = response.json()\n", - " for message in data:\n", - " conversation_data.append({\n", - " \"id\": message[\"id\"],\n", - " \"content\": message[\"content\"],\n", - " \"feedback\": message[\"feedback\"]\n", - " })\n", + " # Dynamically set max_length based on input length\n", + " input_length = len(content.split())\n", + " max_length = max(10, int(input_length * 0.8))\n", + " \n", + " # Summarize the content\n", + " summary = summarizer(content, max_length=max_length, min_length=5, do_sample=False)[0]['summary_text']\n", + " summarized_issues.append(summary)\n", + " \n", + " # Classify the content into categories\n", + " classification = classifier(content, candidate_labels=categories)\n", + " top_category = classification['labels'][0]\n", + " categorized_issues[top_category].append(content)\n", " \n", - " print(json.dumps(conversation_data, indent=2)) # For verification or further processing\n", - "else:\n", - " print(f\"Request failed with status code {response.status_code}\")\n", - " print(response.text) " + " return summarized_issues, categorized_issues\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Perform the analysis\n", + "summarized_issues, categorized_issues = analyze_negative_feedback_with_llm(conversation_data)\n", + "\n", + "# Print the summarized issues\n", + "# print(\"Summarized Issues:\")\n", + "# for summary in summarized_issues:\n", + "# print(summary)\n", + "\n", + "# Print categorized issues and identify incorrect information\n", + "print(\"\\nCategorized Issues:\")\n", + "for category, contents in categorized_issues.items():\n", + " print(f\"\\n{category}:\")\n", + " for content in contents:\n", + " print(f\" - {content}\")" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Topic 0:\n", - "merchant involved 2021-02-01 merchants average\n", - "Topic 1:\n", - "transaction card used transactions 2021-04-17\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/luzhou/Documents/github/CoPilot/venv/lib/python3.11/site-packages/sklearn/feature_extraction/text.py:521: UserWarning: The parameter 'token_pattern' will not be used since 'tokenizer' is not None'\n", - " warnings.warn(\n" - ] - } - ], + "outputs": [], "source": [ "from sklearn.feature_extraction.text import CountVectorizer\n", "from sklearn.decomposition import LatentDirichletAllocation\n", "\n", - "# Extract feedback messages\n", - "feedback_messages = [item['content'] for item in conversation_data if item['feedback'] == 0]\n", + "# Extract negative feedback messages\n", + "feedback_messages = [item['question'] for item in conversation_data]\n", "\n", "# Custom tokenizer to handle specific patterns\n", "def custom_tokenizer(text):\n", @@ -1638,46 +448,22 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Clustering results:\n", - "Cluster 0:\n", - "- The transactions from 2/1/21 to 5/1/21 that were above the average amount for that card are as follows: Transaction with id 39843 on 2021-04-17 with amount 7855.36, transaction with id 40831 on 2021-04-24 with amount 2934.13, transaction with id 871054 on 2021-02-02 with amount 5321.52, transaction with id 769 on 2021-04-17 with amount 2802.55, transaction with id 34336 on 2021-04-24 with amount 4935.42, transaction with id 473824 on 2021-04-18 with amount 3713.09, and transaction with id 7815 on 2021-04-17 with amount 6044.24.\n", - "- Provide more details about this transaction 871054, like the card used and merchant involved in this transaction.\n", - "- The transaction with the ID 871054 was a payment transaction that occurred at the time 2021-02-02 00:00:00. The amount involved in this transaction was 5321.52. The transaction was marked as fraudulent. However, the details about the card used and the merchant involved in this transaction are not provided in the given context.\n", - "- what merchant is involved in the transaction 871054?\n", - "- The merchant involved in the transaction 871054 is fraud_Kuhn LLC.\n", - "- what card is used in the transaction 871054?\n", - "- The context does not provide information on what card was used in transaction 871054.\n", - "Cluster 1:\n", - "- Find all transactions, from 2/1/21 to 5/1/21 above average amount for that card. Sort the results.\n", - "- List all merchants that have more than 2500 transactions from 2021-02-01 to 2021-10-01.\n", - "- The merchants that have more than 2500 transactions from 2021-02-01 to 2021-10-01 are Kilback LLC with 2909 transactions and Kuhn LLC with 2610 transactions.\n", - "\n", - "Cluster centroids (top words per cluster):\n", - "Cluster 0 words: transaction 871054 involved merchant used card provide id fraud_kuhn context\n", - "Cluster 1 words: 01 transactions 2021 21 2500 10 merchants llc sort results\n" - ] - } - ], + "outputs": [], "source": [ "from sklearn.feature_extraction.text import TfidfVectorizer\n", "from sklearn.cluster import KMeans\n", "\n", "# Extract feedback messages\n", - "feedback_messages = [item['content'] for item in conversation_data if item['feedback'] == 0]\n", + "feedback_messages = [item['question'] for item in conversation_data]\n", "\n", "# Vectorize the feedback messages\n", "vectorizer = TfidfVectorizer(stop_words='english')\n", "X = vectorizer.fit_transform(feedback_messages)\n", "\n", "# Apply K-means clustering\n", - "num_clusters = 2 # Number of clusters\n", + "num_clusters = 4 # Number of clusters\n", "kmeans = KMeans(n_clusters=num_clusters, random_state=42)\n", "kmeans.fit(X)\n", "\n", @@ -1690,7 +476,7 @@ " for message in cluster_messages:\n", " print(f\"- {message}\")\n", "\n", - "# Optional: Print cluster centroids (important words for each cluster)\n", + "# Print cluster centroids (important words for each cluster)\n", "print(\"\\nCluster centroids (top words per cluster):\")\n", "order_centroids = kmeans.cluster_centers_.argsort()[:, ::-1]\n", "terms = vectorizer.get_feature_names_out()\n", From 3528b6293819659daa3932a37bc53cdcf1706cf5 Mon Sep 17 00:00:00 2001 From: Lu Zhou Date: Sun, 28 Jul 2024 11:07:11 -0700 Subject: [PATCH 3/3] finalize the notebook to do feedback analysis --- copilot/app/agent/agent.py | 2 +- copilot/docs/notebooks/FeedbackAnalysis.ipynb | 640 +++++++++--------- .../notebooks/TransactionFraud_demo.ipynb | 86 ++- copilot/requirements.txt | 2 + 4 files changed, 363 insertions(+), 367 deletions(-) diff --git a/copilot/app/agent/agent.py b/copilot/app/agent/agent.py index d7e8b279..25cabec4 100644 --- a/copilot/app/agent/agent.py +++ b/copilot/app/agent/agent.py @@ -141,7 +141,7 @@ def question_for_agent( for output in self.agent.stream({"question": input_data["input"], "conversation": input_data["conversation"]}): for key, value in output.items(): - logger.info(f"testing steps {key}: {value}") + # logger.info(f"testing steps {key}: {value}") LogWriter.info(f"request_id={req_id_cv.get()} executed node {key}") LogWriter.info(f"request_id={req_id_cv.get()} EXIT question_for_agent") diff --git a/copilot/docs/notebooks/FeedbackAnalysis.ipynb b/copilot/docs/notebooks/FeedbackAnalysis.ipynb index 3fb4adce..447882c8 100644 --- a/copilot/docs/notebooks/FeedbackAnalysis.ipynb +++ b/copilot/docs/notebooks/FeedbackAnalysis.ipynb @@ -2,70 +2,13 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ - "import re\n", "import requests\n", - "import json\n", "import base64\n", "\n", - "from fastapi import HTTPException, status\n", - "from pyTigerGraph import TigerGraphConnection\n", - "# from app.common.config import db_config\n", - "\n", - "# Define roles with full access\n", - "ALLOWED_ROLES = {'superuser', 'globaldesigner', 'admin'}\n", - "\n", - "user_role_pattern = r'- Name:\\s+(.+?)\\s+- Global Roles:\\s+(.+?)\\s+-'\n", - "\n", - "def get_user_role(username: str, password: str, conn=None) -> tuple[list[str], TigerGraphConnection]:\n", - " if conn is None:\n", - " conn = TigerGraphConnection(\n", - " # host=db_config[\"hostname\"], graphname=\"\", username=username, password=password\n", - " host=\"tigergraph_host\",\n", - " graphname=\"\", username=username, password=password\n", - " )\n", - "\n", - " try:\n", - " # parse user info\n", - " info = conn.gsql(\"SHOW USER\")\n", - " user_roles = {}\n", - " # print (info)\n", - " for match in re.finditer(user_role_pattern, info):\n", - " name = match.group(1).strip()\n", - " global_roles = match.group(2).strip()\n", - " user_roles[name] = global_roles\n", - "\n", - " except requests.exceptions.HTTPError as e:\n", - " raise HTTPException(\n", - " status_code=status.HTTP_401_UNAUTHORIZED,\n", - " detail=\"Incorrect username or password\",\n", - " )\n", - " except Exception as e:\n", - " raise e\n", - " return user_roles, conn" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "user_roles, conn = get_user_role(username=\"USERNAME\", password=\"PASSWORD\")\n", - "\n", - "for user, roles in user_roles.items():\n", - " print (f\"{user}: {roles}\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ "def create_headers(username, password):\n", " \"\"\"Create headers with Base64 encoded credentials.\"\"\"\n", " credentials = f\"{username}:{password}\"\n", @@ -78,14 +21,14 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "def get_user_conversation_ids(username, password):\n", " \"\"\"Fetch conversation IDs for a given user.\"\"\"\n", " headers = create_headers(username, password)\n", - " user_url = f'http://0.0.0.0:8000/ui/user/{username}'\n", + " user_url = f'http://COPILOT_ADDRESS/ui/user/{username}'\n", " \n", " response = requests.get(user_url, headers=headers)\n", " \n", @@ -100,45 +43,25 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "get_user_conversation_ids(\"supportai\", \"supportai\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "def get_conversation_data(username, password, conversation_id):\n", " \"\"\"Fetch conversation data for a given conversation ID.\"\"\"\n", " headers = create_headers(username, password)\n", - " conversation_url = f'http://0.0.0.0:8000/ui/conversation/{conversation_id}'\n", + " conversation_url = f'http://COPILOT_ADDRESS/ui/conversation/{conversation_id}'\n", " \n", " response = requests.get(conversation_url, headers=headers)\n", " \n", " if response.status_code == 200:\n", " data = response.json()\n", - " # return [\n", - " # {\n", - " # \"id\": message[\"id\"],\n", - " # \"message_id\": message[\"message_id\"],\n", - " # \"parent_id\": message[\"parent_id\"],\n", - " # \"role\": message[\"role\"],\n", - " # \"content\": message.get(\"content\", \"\"),\n", - " # \"feedback\": message.get(\"feedback\", \"\")\n", - " # }\n", - " # for message in data\n", - " # ]\n", - " \n", + "\n", " # Create dictionaries to hold user questions and system answers\n", " questions = {message[\"message_id\"]: message for message in data if message[\"role\"] == \"user\"}\n", " answers = {message[\"parent_id\"]: message for message in data if message[\"role\"] == \"system\"}\n", " \n", - " # return questions, answers\n", + " # Return questions, answers\n", " # Organize into Q&A pairs\n", " qa_pairs = []\n", " for q_id, question in questions.items():\n", @@ -158,47 +81,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ - "def check_user_role(username, password, user_roles, conversation_id=None):\n", - " \"\"\"Check user role and permissions for accessing conversations.\"\"\"\n", - " if username not in user_roles:\n", - " return \"User does not exist in the database.\"\n", - " \n", - " if user_roles.get(username) in {'superuser', 'globaldesigner', 'admin'}:\n", - " return True # Allow access for superusers, global designers, and admins\n", - " elif conversation_id:\n", - " # For non-superuser roles, check if the conversation belongs to the user\n", - " conversation_ids = get_user_conversation_ids(username, password)\n", - " if conversation_id in conversation_ids:\n", - " return True\n", - " else:\n", - " return False\n", - " else:\n", - " return False" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def fetch_user_conversations(username, password, user_roles, conversation_id=None):\n", - " \"\"\"Fetch conversations based on user roles and permissions.\"\"\"\n", - " permission_check = check_user_role(username, password, user_roles)\n", - " if permission_check is not True:\n", - " return permission_check # Return the error message if permissions are insufficient or user does not exist\n", - "\n", + "def fetch_user_conversations(username, password, conversation_id=None):\n", " if conversation_id:\n", - " # Fetch a specific conversation\n", - " data = get_conversation_data(username, password, conversation_id)\n", - " if data:\n", - " return data\n", - " else:\n", - " return \"Conversation not found or could not be retrieved.\"\n", + " conversations = {}\n", + " # Fetch a specific conversation\n", + " data = get_conversation_data(username, password, conversation_id)\n", + " \n", + " if data:\n", + " conversations[conversation_id] = data\n", + " return conversations\n", + " else:\n", + " return \"Conversation not found or could not be retrieved.\"\n", " \n", " else:\n", " # Fetch all conversations\n", @@ -215,277 +112,360 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ - "conversation_data = fetch_user_conversations(\"USERNAME\", \"PASSWORD\", user_roles, \"CONVO_ID\")" + "conversation_data = fetch_user_conversations(\"YOUR_DB_USERNAME\", \"YOUR_DB_PASSWORD\")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ - "def get_feedback_stats(conversation_data):\n", - " # Initialize counters\n", - " feedback_counts = {'No Feedback': 0, 'Thumbs Up': 0, 'Thumbs Down': 0}\n", - " total_entries = len(conversation_data)\n", - " \n", - " # Count feedback occurrences\n", - " for entry in conversation_data:\n", - " feedback = entry['feedback']\n", - " if feedback == 0:\n", - " feedback_counts['No Feedback'] += 1\n", - " elif feedback == 1:\n", - " feedback_counts['Thumbs Up'] += 1\n", - " elif feedback == 2:\n", - " feedback_counts['Thumbs Down'] += 1\n", - " \n", - " # Calculate percentages\n", - " feedback_percentages = {k: (v / total_entries) * 100 for k, v in feedback_counts.items()}\n", + "import openai\n", + "from sklearn.cluster import KMeans\n", + "import matplotlib.pyplot as plt\n", + "\n", + "openai.api_key = 'OPENAI_API_KEY'\n", + "\n", + "questions = []\n", + "feedbacks = []\n", + "for i in conversation_data.values():\n", + " for j in i:\n", + " questions.append(j.get('question'))\n", + " feedbacks.append(j.get('feedback'))\n", + "\n", + "def get_embeddings(questions):\n", + " response = openai.embeddings.create(\n", + " input=questions,\n", + " model=\"text-embedding-ada-002\"\n", + " )\n", + " return [embedding.embedding for embedding in response.data]\n", + "\n", + "embeddings = get_embeddings(questions)\n", + "\n", + "# Determine the optimal number of clusters using the elbow method\n", + "def plot_elbow_method(embeddings, max_clusters=10):\n", + " inertias = []\n", + " for n in range(1, max_clusters + 1):\n", + " kmeans = KMeans(n_clusters=n, random_state=0)\n", + " kmeans.fit(embeddings)\n", + " inertias.append(kmeans.inertia_)\n", " \n", - " return feedback_counts, feedback_percentages" + " plt.figure(figsize=(8, 6))\n", + " plt.plot(range(1, max_clusters + 1), inertias, marker='o')\n", + " plt.xlabel('Number of clusters')\n", + " plt.ylabel('Inertia/WCSS')\n", + " plt.title('Elbow Method For Optimal Number of Clusters')\n", + " plt.show()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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S5cuQRRFrdct7LmlzVHU/q5duwYbG5tSLx31+uuvIzw8HL/88gsGDx5c4PG7d+/iyJEjCAgIKPCX9s2bN9G5c2fN/fT0dMTFxWnW9AXK53Morq1bt2LYsGFaKxpkZWUhOTm53F7j//7v/7Bu3TrNSUbPyz9K+t/Xe/63JOUt/whuPlEUcevWLTRr1gwANCeCmpubv/RnpqSK+/NREkFBQZgzZw7WrVtXqsJb0s/AwcEB48aNw7hx45CYmIgWLVrgiy++0BTeor5/69ati/Pnz6NLly5l+h43MDBAUFAQgoKCoFarMW7cOPz444+YMWNGtV9nncqGc3iJSmjJkiVa9/MXz8//Az2/nPz3akL5Ry569Oih2ebu7o7atWvju+++Q25uLtq2bQvgWRG+ffs2tm7ditatW0NPr+T/Nh01ahRmzZpV5PJLwLMjIp06dcKPP/5Y6DzKhw8fav4/vwCWpey89tpriIiIQHh4uGZbRkYGli9fDjc3N82cvNdeew0PHjzQusxrZmYmli9fXurXfp6DgwOaN2+O1atXa72fS5cuYe/evVoFs6Teffdd2NraYtq0aQXmiGZlZWHEiBEQRREzZ84s8Nzly5cjNzdXc3/ZsmXIy8vTOjpmYmJSroXzReRyeYGjoN9///0Lj7CWVN26dTF48GDNcm7PMzc3h42NjWaee76lS5eW2+v/15o1a7SmpGzduhVxcXGaz8DHxwd169bF119/jfT09ALPf/5npqSK+/NREv7+/ujWrRt++umnAisdAEBOTs4LL15R3M9ApVIVmOZia2sLR0dHrWXFTExMCp0O07dvX9y/fx8rVqwo8NjTp0+RkZFRZMZ8/52iIpPJNP9QKe8lDan64RFeqpH++usvzVGT57Vp0+al882ioqLQs2dPdOvWDeHh4Vi3bh0GDhwILy8vAICXlxeGDRuG5cuXIzk5GR07dkRERARWr16NXr16aR3BA56V202bNqFp06aaoyktWrSAiYkJbty4UeL5u/lcXV211sgsypIlS9CuXTs0bdoUo0ePRp06dZCQkIDw8HDcu3cP58+fB/DsYgFyuRzz5s1DSkoKDA0N8corr8DW1rbYmaZPn46NGzeie/fumDRpEqysrLB69WpERUXh119/hUz27N/go0ePxuLFizF06FCcOXMGDg4OWLt2bamXwSrMV199he7du8Pf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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plot the elbow method graph to determine the best number of clusters\n", + "plot_elbow_method(embeddings)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ - "# Get feedback stats\n", - "feedback_counts, feedback_percentages = get_feedback_stats(conversation_data)\n", + "optimal_cluster = 6\n", "\n", - "print(\"Feedback Counts:\", feedback_counts)\n", - "print(\"Feedback Percentages:\", feedback_percentages)" + "kmeans = KMeans(n_clusters=optimal_cluster, random_state=0)\n", + "kmeans.fit(embeddings)\n", + "labels = kmeans.labels_" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ - "import openai\n", + "# Group questions by their cluster labels\n", + "clustered_questions = {i: [] for i in range(optimal_cluster)}\n", + "for i, label in enumerate(labels):\n", + " clustered_questions[label].append(questions[i])" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "def generate_summary(questions):\n", "\n", - "# Set your OpenAI API key\n", - "openai.api_key = 'APIKEY'\n", - "\n", - "# def summarize_text(text):\n", - "# response = openai.chat.completions.create(\n", - "# model=\"gpt-4\", \n", - "# messages=[\n", - "# {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n", - "# {\"role\": \"user\", \"content\": f\"Summarize the following text:\\n\\n{text}\"}\n", - "# ],\n", - "# max_tokens=100, # Adjust the number of tokens as needed\n", - "# temperature=0.1\n", - "# )\n", - "# return response.choices[0].message.content.strip()\n", - "\n", - "def classify_text(text, labels):\n", + " # Call OpenAI API to generate a summary\n", " response = openai.chat.completions.create(\n", - " model=\"gpt-4\",\n", - " messages = [\n", - " {\"role\": \"system\", \"content\": \"You are an assistant that classifies text into categories.\"},\n", - " {\"role\": \"user\", \"content\": f\"Classify the following text into one of these categories: {', '.join(labels)}\\n\\nText:\\n{text} and just return the labels only\"}\n", + " model=\"gpt-4o-mini\",\n", + " messages=[\n", + " {\"role\": \"system\", \"content\": \"you are an expert to summary texts into a short and concise theme\"},\n", + " {\"role\": \"user\", \"content\":f\"summarize the following questions into a main theme, and only return the label of theme, questions: {questions}\"}\n", " ],\n", - " max_tokens=50, # Adjust the number of tokens as needed\n", + " max_tokens=20,\n", " temperature=0.1\n", " )\n", - " return response.choices[0].message.content.strip()" + " \n", + " # Extract and return the generated summary\n", + " summary = response.choices[0].message.content.strip()\n", + " return summary" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cluster 0:\n", + " - Provide more details about this transaction 871054, like the card used and merchant involved in this transaction.\n", + " - Are there any activities of the user associated with transaction 871054 that might be interesting to look into for further investigation? \n", + " - What are more details of the transaction 565964?\n", + "Main theme: Transaction Details and Investigation\n", + "\n", + "Cluster 1:\n", + " - what is the merchant involved in this transaction?\n", + " - What do we know about this merchant?\n", + "Main theme: Merchant Information\n", + "\n", + "Cluster 2:\n", + " - Find all transactions, from 2/1/21 to 5/1/21 above average amount for that card. Sort the results.\n", + " - List all merchants that have more than 2500 transactions from 2021-02-01 to 2021-10-01.\n", + "Main theme: Transaction Analysis\n", + "\n", + "Cluster 3:\n", + " - what is the card used in this transaction?\n", + " - What is the ID of the card used in transaction 565964?\n", + "Main theme: Card Transaction Identification\n", + "\n", + "Cluster 4:\n", + " - List the largest 10 transactions made by the merchant fraud_Kuhn LLC?\n", + "Main theme: Merchant Fraud Transactions\n", + "\n", + "Cluster 5:\n", + " - How many transactions are there?\n", + "Main theme: Transaction Count Inquiry\n", + "\n" + ] + } + ], "source": [ - "feedback_messages = [item['question'] for item in conversation_data]\n", - "\n", - "# Define labels for classification\n", - "labels = [\"Missing Information\", \"Incorrect Information\", \"Irrelevant Information\"]\n", - "\n", - "# Process each piece of conversation data\n", - "# for i, text in enumerate(feedback_messages):\n", - "# # summary = summarize_text(text)\n", - "# classification = classify_text(text, labels)\n", - "# # print(f\"Conversation {i+1} Summary: {summary}\")\n", - "# print(f\"Message: {text}\")\n", - "# print(f\"Classification: {classification}\")\n", - "# print(\"---\")\n", - "\n", - "# Print the results in the desired format\n", - "# Initialize a dictionary to store classified issues\n", - "classified_issues = {category: [] for category in labels}\n", - "\n", - "results = {}\n", - "\n", - "for message in feedback_messages:\n", - " result = classify_text(message, labels)\n", - " results[message] = result\n", - "# Categorize each piece of text\n", - "for text, category in results.items() :\n", - " if category in classified_issues:\n", - " classified_issues[category].append(text)\n", - " else:\n", - " classified_issues['Other'].append(text)\n", - "\n", - "# Print the results in the desired format\n", - "print(\"\\nCategorized Issues:\\n\")\n", - "for category in labels:\n", - " if classified_issues[category]:\n", - " print(f\"{category}:\")\n", - " for issue in classified_issues[category]:\n", - " print(f\" - {issue}\")\n", - " print() # Add a newline for better readability" + "main_themes = {}\n", + "\n", + "# Print questions for each cluster and use ChatGPT to summarize the main theme\n", + "for cluster, qs in clustered_questions.items():\n", + " print(f\"Cluster {cluster}:\")\n", + " for q in qs:\n", + " print(f\" - {q}\")\n", + " # Summarize main theme using ChatGPT or another method\n", + " theme_summary = generate_summary(qs) # Define this function or use an LLM\n", + " print(f\"Main theme: {theme_summary}\\n\")\n", + " main_themes[cluster] = theme_summary" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ - "from transformers import pipeline\n", - "from tqdm import tqdm\n", - "\n", - "# Load summarization and zero-shot classification pipelines\n", - "summarizer = pipeline(\"summarization\", model=\"facebook/bart-large-cnn\")\n", - "classifier = pipeline(\"zero-shot-classification\", model=\"facebook/bart-large-mnli\")\n", - "\n", - "def analyze_negative_feedback_with_llm(conversation_data):\n", - " negative_feedback_entries = [entry for entry in conversation_data if entry['feedback'] == 2]\n", - " \n", - " # Define categories for classification\n", - " categories = [\"Missing Information\", \"Incorrect Information\", \"Irrelevant Information\", \"Other\"]\n", - " \n", - " summarized_issues = []\n", - " categorized_issues = {category: [] for category in categories}\n", - " \n", - " for entry in negative_feedback_entries:\n", - " content = entry['content']\n", - "\n", - " # Dynamically set max_length based on input length\n", - " input_length = len(content.split())\n", - " max_length = max(10, int(input_length * 0.8))\n", - " \n", - " # Summarize the content\n", - " summary = summarizer(content, max_length=max_length, min_length=5, do_sample=False)[0]['summary_text']\n", - " summarized_issues.append(summary)\n", - " \n", - " # Classify the content into categories\n", - " classification = classifier(content, candidate_labels=categories)\n", - " top_category = classification['labels'][0]\n", - " categorized_issues[top_category].append(content)\n", - " \n", - " return summarized_issues, categorized_issues\n" + "import matplotlib.pyplot as plt\n", + "from sklearn.decomposition import PCA\n", + "\n", + "def plot_kmeans_clusters(embeddings, feedbacks, optimal_clusters):\n", + " \"\"\"\n", + " Perform KMeans clustering, reduce dimensions using PCA, and plot the clusters in 2D.\n", + "\n", + " Parameters:\n", + " - embeddings: Array-like, shape (n_samples, n_features)\n", + " The input data to be clustered.\n", + " - feedbacks: Array-like, shape (n_samples,)\n", + " An array indicating the type of feedback for each sample (1 or 2).\n", + " - optimal_clusters: int\n", + " The number of clusters to form.\n", + "\n", + " Returns:\n", + " - None: Displays a 2D plot of the clustered data.\n", + " \"\"\"\n", + "\n", + " # Perform KMeans clustering with the optimal number of clusters\n", + " kmeans = KMeans(n_clusters=optimal_clusters, random_state=0)\n", + " clusters = kmeans.fit_predict(embeddings)\n", + "\n", + " # Perform PCA to reduce dimensions to 2 for 2D plotting\n", + " pca = PCA(n_components=2)\n", + " reduced_embeddings = pca.fit_transform(embeddings)\n", + "\n", + " # Plotting the clusters in 2D\n", + " fig, ax = plt.subplots(figsize=(12, 8))\n", + "\n", + " # Define colors for clusters\n", + " colors = ['r', 'g', 'b', 'c', 'm', 'y', 'k']\n", + "\n", + " # Plot each cluster with different color and annotate\n", + " for cluster in range(optimal_clusters):\n", + " cluster_points = reduced_embeddings[clusters == cluster]\n", + " ax.scatter(cluster_points[:, 0], cluster_points[:, 1], c=colors[cluster % len(colors)], label=f'Cluster {cluster}')\n", + "\n", + " for cluster in main_themes:\n", + " cluster_center = kmeans.cluster_centers_[cluster]\n", + " reduced_center = pca.transform([cluster_center])[0]\n", + " ax.text(reduced_center[0], reduced_center[1], main_themes[cluster], fontsize=12, weight='bold')\n", + "\n", + " # Highlight feedback with different markers\n", + " for i, (x, y) in enumerate(reduced_embeddings):\n", + " if feedbacks[i] == 1:\n", + " ax.scatter(x, y, c='black', marker='^')\n", + " elif feedbacks[i] == 2:\n", + " ax.scatter(x, y, c='black', marker='x')\n", + "\n", + " ax.set_xlabel('PCA Component 1')\n", + " ax.set_ylabel('PCA Component 2')\n", + " ax.legend()\n", + " plt.show()\n", + "\n", + " return clusters, main_themes" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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z3rGpH1XGDZsmKlRo4bx8fExJUqUME2aNDHjx483qampTn3T1xEWFmZ27txpOnXqZIoXL24CAwPN448/7vQZKjOOn3kur2XTpk3G09PTWj5x4kSn5Xv27DGPPPKIqVixovH29jZlypQx3bt3N7///rvVJyoqKtNtERYWZowx5tChQ6Zfv36mXr16plSpUsbT09MEBgaa1q1bmwULFmTYp5d/XzDG+fOn4zGY3WPAlaupKzo62jRq1MjY7XYTGhpqPvjggwzr37Rpk2nZsqXx8fEx5cuXN8OHDzfLly93+foy4/iemDx5ssv29PdK+uf3tm3bWu+VCxcuWN8TSpYsmeF4T//sa7fbzalTp6z2hQsXmttvv90EBAQYb29vU61aNTN8+HBz9uxZp8fv3bvX3HfffSYkJMR4enoaf39/U7NmTdO3b1+zefNmY4zJ9PhwfE2O/8Y4OnHihOndu7fx8/Mz/v7+5sEHHzTHjx/PcIzlZH86vidc3Vztb0dxcXHmmWeeMVWqVDHe3t7G39/ftGzZ0syZMyfDtnF8761fv960atXKFC1a1AQFBZmXXnrJpKSkZH0A4KoQXl0B4dUqq93xDSvJVK1a1UyfPt0sXbrU+gdk0qRJZtKkSWbJkiUmJibGLFmyxPTu3dt6zIwZM6z1Of4j7evra8aPH2+mT59uAgICrPbffvvNGGPM2LFjrbYBAwaYFStWmLlz55oRI0aYRo0amd27d1vrff31183MmTNNdHS0iYmJMfPnzzdNmza1ApODBw8aY9L+QXQMurp06WIWLFhg5s6dax599FEzY8YMk5CQYGJjY02DBg2sfl9++aWJjY01sbGx5q+//sr0A80TTzxhtdetW9fMnz/fTJw40QQGBlrts2bNsvo7btsaNWqYefPmmTfeeMNqK126dLb2308//WQ95v/+7/+MMcY88sgjVtv8+fOd+jt+ePDy8jJvv/22mT9/vgkNDbXaFy9ebPXP7T5OD68cA6lRo0ZZfbt27Wq179mzxxhjzL333muktBBu/PjxZsWKFWbGjBnmueeeMy1atLAe6yq8+vXXX622tm3bmujoaLN48WIzduxY06FDB/P5559na3sCAHC94YfKf75oF7YfKrMKr4xx/sx3++23W+0bNmxw+ozteCtRooT58ccfjTHZC6/Wrl2b5TabOnWq9bw5Ca9ycgy4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z7e+2+T0/SKljW7asWOHJOmnn36yvkc5jv5zlNP9eXlNjn+7UrVqVes4/+OPP3Ty5Elr9FVBvYeRNcIr5JlOnTopJCREcXFx2rRpkzU8u3nz5k6/AuVGamqqYmNjnYILR+mhxyOPPKKJEyfKGKMvvvhCX3zxhWw2myIiIjL8w1i+fHl99NFHevzxx5Wamqr58+c7jcZxHC7aunVra9moUaM0atQohYWFad++fZnW/OabbyomJkbbt2/X5s2bdc899zgt79mzp/WhLy+sWLHCCmZuvvlm6386l/dZuHChLly4oPnz5zudvpcdebmPH3jgAb3wwgtWiOTt7Z1hG507d07z5s3TvHnzMjy+aNGi6ty5c5bPsWPHDr3xxhsul+VlcAgAwI2AHyr/URA/VF4uMTFRa9asUXJysmJjY/XRRx8pJSVFknTLLbeoT58+kqT69eurTp06+u233/T999+rd+/e6tatm7y8vLRv3z6tX79eCxYssE6DlNK2x6lTp3TkyBHNmDFDYWFhCgoKUnh4uMLCwrRr1y6dPHlSo0aNUr169fTBBx9YU1TkVnaPgczkV10eHh7617/+pdmzZ0uSHnzwQb3yyis6fPiwxowZc1XrvhoPPPCANm7cqPj4eMXHx0uS7r//fqfg+f7779cHH3wgSRo0aJBOnTqlevXqKSEhQX/88Ye+/fZbhYWFadKkSTn64dfx/TJv3jxVrlxZXl5eaty4sXXK4uW6dOline3y6quvqmjRoipevLiGDBnisn9O92dgYKD27t0rKW3U1i233CJ/f3+nkVqOSpUqpXbt2ik6Olrnz59X9+7dNWjQIP3xxx/6+OOPrX58Z3Aj13aKrcKHCdtXWe2ZXWnF0W+//WbatGljSpQoYcqXL29ef/11s2LFCpcTGWY2MaarCQB3795tBgwYYG6++WZTunRpU6RIEePv728iIyPN7NmznWpYuHChqVu3rvHx8TG1a9c2c+fOzXJSwR9++MHcc889JigoyHh6epqyZcuaDh06OE2keeHCBTNkyBBTsWJF61K66RMKZrVdEhISzNChQ0316tWN3W43xYsXN40bNzb//e9/TWpqqlPf9HVcPlFhVhOIOnKc+PK1115z2cfxCjRt27bN8DjH/e1qEnRj8mYfp+vRo4e13HFC03QrV640ffr0MdWrVzf+/v6mSJEipmzZsqZLly5Ok4q6qvXMmTMmKirKtGzZ0oSEhBgvLy9TtGhRU69ePTNixAhz4cKFTLclAADXs9x+1ktKSjIhISEZJk12vLhMbj/rTZs2LcN6HW8zZ840xqRd+ObyiZttNpvTxOOOn/UmTJhgfXa7/ObYz3GS9cs/k2W2XU6ePOk02frlt549ezp93rvaz3rGOH/myezWtGlTc+TIEafHbdiwwekqj65uju69994My9P37TvvvJNhWenSpU316tUzvI6cTNie3WMgM3lRV2b7aefOncbPzy/D+sPDwzNdjyvZmbA9vcbLJ2y//DvMkSNHrKtFpt+2bNmS4Tkdr0Lo6pZe98GDB7Ps9/jjj1vr3LJli8sJ1NNrdzV5+oULF0yjRo0yPKZevXout3lO9qcxzpOsX/5+zWx///HHH05XKbz8NmTIEKtvVv8+ZjVZPPIOW/cKbsTwCrhWpk6dav1Df3kICQAA8gc/VBbOHyqNyRheeXh4mOLFi5sqVaqYTp06mRkzZpiLFy+6fOy+ffvME088YapUqWK8vb1NQECAqVOnjnniiSfMihUrnPrGxcWZ7t27mzJlymTYt5cuXTIjRowwYWFhplixYqZVq1Zmy5YtLl9HTsKrnBwDruRFXcZkvp82bNhgbrvtNmO3201wcLAZMmSI05XyrnV4ZYwx//d//+cUAmVm8eLFpn379qZUqVLGy8vLlC9f3rRo0cKMGjXKupp5Tn/4nTZtmqlZs6bTVUezCq+MMebEiRPmwQcfNH5+fsbPz8/cd999ZteuXVZfxyux52R/GpMWrj/22GOmXLlyVrB2pfDKmLQQsH///qZy5crGy8vL+Pn5mdtuuy3DMUd4VfBsxlzlrIDXuaSkJPn7+ysxMVF+fn4FXQ5wXTh79qxOnjyp3r17KyYmRgEBATpy5IiKFi1a0KUBAAAABe56/B5qjMkwn150dLQ6dOggSbrrrrsyvSo6wJxXAK65WrVqaf/+/dbf//73vwmuAAAAgOtYnz591LhxY0VGRiowMFAbN27UoEGDrOXpFxkAXCG8AlBgQkJC9NBDD+nFF18s6FIAAAAA5KMDBw44XRHTUY8ePZgcHVkivAJwzWV1lUYAAAAA15/77rtPly5d0o4dO5SQkCBfX1/Vr19fffv2Ve/evTOcUgg4Ys6rK7gezzUGAAAAALgvvocCzjwKugAAAAAAAAAgM4RXAAAAAAAAcFuFLrwaN26cKlWqJB8fHzVt2lTr16/PtO/WrVt17733qlKlSrLZbBozZsy1KxQAAAAAAABXrVCFV7Nnz9bgwYMVFRWljRs3qn79+mrXrp2OHTvmsv/Zs2dVpUoVjRo1SsHBwde4WgAAAAAAAFytQhVevf/++3r00UfVr18/1apVS+PHj1exYsU0adIkl/0bN26sd955Rz179pTdbr/G1QIAAAAAAOBqFZrw6sKFC9qwYYPatm1rtXl4eKht27Zau3Ztnj3P+fPnlZSU5HQDAAAAAABAwSg04dWJEyeUkpKioKAgp/agoCDFx8fn2fOMHDlS/v7+1i00NDTP1g0AAAAAAICcKTTh1bUydOhQJSYmWreDBw8WdEkAAAAAAAA3LM+CLiC7SpcurSJFiujo0aNO7UePHs3TydjtdjvzYwEAAAAAALiJQjPyytvbW7fccotWrFhhtaWmpmrFihWKiIgowMoAAAAAAACQXwrNyCtJGjx4sPr06aNGjRqpSZMmGjNmjM6cOaN+/fpJknr37q3y5ctr5MiRktImef/999+t+4cPH9Yvv/yiEiVKqGrVqgX2OgAAAAAAAJA9hSq86tGjh44fP65XX31V8fHxatCggaKjo61J3A8cOCAPj38Gkx05ckQNGza0/n733Xf17rvvqmXLloqJibnW5QMAAAAAACCHbMYYU9BFuLOkpCT5+/srMTFRfn5+BV0OAAAAAOA6x/dQwFmhmfMKAAAAAAAANx7CKwAAAAAAALgtwisAAAAAAAC4LcIrAAAAAAAAuC3CKwAAAAAAALgtwisAAAAAAAC4LcIrAAAAAAAAuC3CKwAAAACA22nVqpVsNptsNpv27dtX0OVc1ypVqmRt68LG3Wrft2+fVU+rVq2cliUlJal///4KCwtTkSJFZLPZNHDgQMXExFiP6du3b4HUna5v375WLTExMQVaiyPPgi4AAAAAAFDwzpw5o08//VQLFizQ1q1bdebMGYWEhKh27drq2bOnunfvLm9v74IuM4O+fftq6tSp2eobFRWl4cOH529BbigmJsYKIrp06aIGDRoUaD2Z2bdvnypXrmz9bYwpwGoyN2XKFCtQHThwoAICArL1uBdeeEGffPJJ/hWWDfv27dOUKVMkSQ0aNFCXLl0KtJ7sIrwCAAAAgBvc77//rk6dOmnPnj1O7fv27dO+ffu0ZMkS1alTx21DD2QtJiZGr732mqS0kUqX78e5c+fqr7/+KoDKCqcpU6bo+++/l5QWnjqGVyEhIYqNjZUk+fv7Oz1u8eLFkiQvLy9Nnz5d5cqVU/ny5VWyZEnrMUFBQfla+759+6xjoU+fPhnCq5deekmPPPKIJKlu3br5WktOEF4BAAAAwA3s1KlT6tChgw4cOCBJKleunP7973+rbt26Sk5O1vfff6/Jkyfn+fOeOXNGxYsXv+r1OH7ZlqS33npLy5YtkyT169dPDz30kLWsYsWK+VpLYdWoUaOCLuG6Ybfb1aJFC5fLjhw5Iikt4OrevbvTsswec62Fh4crPDy8oMvIgDmvAAAAAOAG9u6771rBlb+/v9avX6+BAwfq9ttvV5cuXTR69Gjt3LnTCn4OHz6shx56SPXr11fp0qXl5eWlkiVLqk2bNlq4cKHTui+fy2f+/Plq0KCB7Ha73nnnHUlSSkqKhg8frvLly6tYsWJq3bq1Nm/enO36w8PD1aJFC+tWtmxZa1nFihWdlt12221WPQcOHNC9994rf39/1alTR5K0evVqdevWTeHh4QoICJC3t7fKlSun7t27a8uWLU7PO3z4cGtdkydP1pgxY1S1alXZ7XbVr19fK1eudOq/b98+3X///SpXrpy8vLwUEBCgWrVqqV+/fk7r/uyzz3T33XdLSgs5fHx8FB4ermeeeUYnTpzI8PoPHjyo/v37q2rVqvLx8VFgYKAiIiI0e/ZsSZLNZrNG2khpgV563emnj2U2b5QxRp9++qmaNWsmX19f+fj4qEaNGho2bJgSExOd+jrOUbZlyxY988wzKlu2rIoWLaoOHTpo//792dqfmTl79qyeffZZlSlTRiVKlNBdd92V5VxoxhhNnjxZzZs3l5+fn4oWLar69evrgw8+UGpqqlNfx9cfHx+vBx98UIGBgfL19VWPHj106tQpSf8cz+mjriSpcuXKTnOzuZrzKv1YST8N8sCBA077IKs5r06dOqWhQ4eqVq1aKlasmPz8/HTzzTfro48+svosXLhQd911lypXrixfX195e3srLCxM/fr1c9pGrVq1UuvWra2/p06dmuF5s5rzauXKlbrzzjtVunRpeXt7KzQ0VH379tWuXbuc+uX0vZEtBllKTEw0kkxiYmJBlwIAAAAAea5KlSpGkpFkhg8ffsX+a9eutfq7uk2dOtXqu2rVKqu9cuXKxmazWX9HRUUZY4x5+umnM6zDz8/PVKpUyfp779692X49ffr0yfAc6cLCwqxljq87LCzMGGPMyJEjM31dxYoVM7///ru1rqioKJfrSr/5+vqaU6dOGWOMuXjxoqlWrVqm654wYYK13nbt2mXar2bNmubcuXNW302bNpmSJUu67NunTx9jjMlyX02ePDnDdkmXmppqevbsmelja9SoYb0+Y4xp2bJlltujefPmV9x3e/fudXqMozvvvDPDOitUqOD0+h317t0709p79OiRreMi/darVy9jjPPx7Oq2d+9ep9fQsmXLDMeKq33guN70/WaMMQcOHDAVK1Z0+bj0dRtjzOOPP57p+oOCgszRo0cz7KPMjhfH98+qVaus5xg3bpzT+/fyY339+vVW35y8N7KLkVcAAAAAcIP6888/nea5ioyMvOJjgoODNWrUKM2bN0/fffedVq1apalTp6pMmTKSpBEjRrh83N69e9WoUSN9+eWXWrhwoSIjI7V9+3Z9/PHHkiQPDw8NHz5cixcvVkRERL5fYfDo0aN6//339e2332rYsGGSpCZNmmjs2LFatGiRVq1apeXLl+vtt9+WlDbyZ/To0S7XtWfPHg0ZMkSLFi1S/fr1JUnJycn64osvJEnbt2/Xzp07JUlt27ZVdHS0Fi9erLFjx6pDhw6y2+3Wunr06KFx48ZJkpYsWaIlS5aod+/ekqRt27Zp/vz5kiRjjHr37m2NCqpTp46mTZumJUuW6NVXX1WpUqUkSbGxserXr5+1/mHDhik2NlaxsbHq2LFjpttnzpw5mjVrliQpMDDQmsy/Xr161mtK326XO378uMaPH6/p06db80H98MMP2rp1a6bPl5VvvvlGS5YskSQVLVpUY8aM0cKFCxUcHGy9fkdz587V559/LkmqXr26Zs6cqa+//lrNmjWTJM2ePdsamXa5c+fOafr06fr444+tCxTMmjVLiYmJatiwoWJjY53mDPvyyy+t7RkSEuJynQ899JA1p5WU9h7Kzj546qmnrFGRFStW1Keffqro6Gj95z//UWhoqNXvjjvu0CeffKKvv/5aMTExio6O1nPPPScp7TifOHGiJGns2LH68MMPrcd16NDBquOll17KtI6DBw9q0KBBMsbIw8NDL7/8spYsWaJu3bpJSjvW+/bt63KC/Su9N7ItR1HXDYiRVwAAAACuV4cOHXIaEbFt27ZsPW7KlCkmMjLSBAQEuByNkf79yXFESYkSJczJkyed1vP2229by7t162a1JyQkmGLFijmNaMmu7I68+vTTTzM89syZM2b48OGmbt26Ts+ffmvYsKHV13F0SefOna32WbNmWe0DBw40xhizfft2q+3BBx80f/zxh0lJSXFZ/4EDB6zXYLfbM9QwaNAgY0zaqKv0Nj8/P3Ps2LFMt4ljremjrTLbLunuuusuq23s2LFW+6+//mq1BwYGmtTUVGOM86ie0aNHW/2feOIJq33hwoWZ1mhM5iOvnnzySavt3//+t9W+c+dOl/07d+5stX344YcmNjbWxMbGmgkTJljt//rXv1y+/gULFljt7du3t9p/+eUXq93xtV5+bLoaeZUuvT19pF86VyOvTp48aTw8PIwkU6RIEadRf5c7efKkGTx4sKlevbopWrRohmPm7rvvzvK5HLkaefX+++9bbffee6/V98KFCyY4ONhatmnTJmNMzt4b2cWE7QAAAABwg7r8amhHjhxRjRo1snzM6NGjNXjw4Cz7JCQkyM/Pz6mtefPmKlmypFOb46ivxo0bO9VVvXp1bdq0KcvnuRqdOnXK0Hbfffdp0aJFmT4mISHBZXvLli2t++kjnhz7h4eHKzIyUrGxsZo2bZqmTZtmzcF0zz336Nlnn5XdbldycrJuvfVWHTp0SJJ0/vz5TGtIH8klSU2bNrVGvuWVy9efrk6dOipWrJjOnj2r06dP6/jx407zjElX3h45ldlxEh4ersDAQJ0+fTrT2p999lmX69y2bZvL9ryuPbd2795tzc1VpUoV1axZ02W/lJQUtW3bNsv3ytXWntmx4OXlpYYNG1oXSNi5c2eGK1nm1fbktEEAAAAAuEGVKFFCVapUsf7+4YcfrviYsWPHWvdfeOEFrVixQrGxsapbt67VfvmE2JIUFBSUo9ounzw8r11ez4EDB6zgqkSJEvr4448VExPjNGm1q9clpZ1Wl87T858xIubv06g8PDy0dOlSvffee2rfvr0qVqyoc+fOad26dXrhhRc0YMAASdKCBQus4EqSJk+erNjYWKfTFTOrwZ1caXvkpdweJ2fOnHHZfi1rzws//PCDFVyFhIRo6tSpWr16tWbOnGn1yc9j5krbP6+2J+EVAAAAANzAevToYd1///33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9evVunVrffXVV4qPj9elS5cyrWHnzp1W25133pn1C86h48eP6/Tp05KkYsWKOV0MpUmTJtZ9xxrS+fn5OY30crU9MuN4tcMjR45csU7H508fnSZJderUsSYLP336tI4fP37FdWXlal5TXrjS8bV3716r7aabblLJkiWtvx33V35q3769PD2drxVUtGhR3XfffZKkX3/9Vb/++qtiYmKUnJwsSdYyAABwY8t2eHXu3DmnDxw2m03//e9/1alTJ7Vs2dLlh1MAAAqSMSk6dWqVoqNH6NSpVTImJduPTb+SraMFCxZYp+TVqFFDs2fPVmxsrEaPHm31SU1Ndbm+9FPpJDn9/9QYI0kKDg7Whg0bNGTIELVo0UKlSpXS6dOnFR0dre7du1unvo0fP9469etf//qXli5dqtjYWOvUxaxqyC+OpzS6+vtyjttCcr09MlO/fn3r/g8//JDdErPNsfb00y0l6cSJE1k+7mpeU1640vGVlcz2V263RWZcvackWacOStL06dOtUwaLFCmiHj165Oq5AADA9SXb4VWNGjX0888/Z2j/6KOP1LlzZ9111115WhgAAFfj+PH5Wreukt59t406dHhF773XRuvWVdLx467npLqcqy/0hw8ftu4//fTT6t69u1q0aKG//vrrqus1xigsLEyjRo1SbGysTpw4oZ9++slanj6XlmMNI0eOVIcOHdSiRQsdPXo0wzqrVatm3V+6dGmWz+/h8c9HguyEX2XKlLHm7jpz5ow1d5ck/fjjjy5ryAuOYcbnn3+uLVu2ZOiTnJxshYyOz79+/Xrr/m+//aazZ89KSgt+ypQpI8l5ZFd8fLy1vrwKynK6nfNK5cqVrft79uyxRs1JzvvLUV5vi8xCskaNGllzkM2cOVNff/21JKl169aZBl4AAODGku3w6u6773aaSNPRRx99pPvuu++a/LIIAMCVHD8+X1u3dtXZs4c0ZUpa2+TJ0tmzh7R1a1elpp7N1XrDwsKs+5MmTdLSpUv14YcfasSIEVdd88yZM3Xbbbfp/fff14IFC7Ry5UotXLjQWp5+iqJjDSNHjtS3336rQYMG6Ztvvsmwzm7duslut0tKG6V077336quvvtKCBQv01FNPacaMGVZfx5E7EyZMUGxsrMsfrdJ5eHg4TaTdq1cvLViwQJMmTVJUVJTVntenffXt21cNGzaUJF26dEmtWrXSW2+9pe+++05LlizRyy+/rGrVqlm133///dZjX331VU2cOFELFy7Ugw8+aLX36NHDClaqVq1qtffu3Vsff/yx7rjjjjw79c9xO48dO1Zr1qzRr7/+mifrzkpQUJB12uRff/2lnj17asmSJXrrrbesUX2Xy+9t4Sh99NXBgwd14MABSZwyCAAAHBTkhFuFARPlAUDhkpp6yfzvfxXMqlUyQ4c6T2Q+bJjMqlU2Exxc5IoTtjtOjJ0uKSnJhISEZJggvXnz5tb9Pn36WP0zmwQ9KirKap88ebIxxphp06ZlWK/jbebMmcYYY3788Udjs9mcltlsNhMREZFhncYYM2HCBOPh4eFynY79HCdZT7+lT7yd2XY5efKk08Tkl9969uxpTYRujOsJvbPaTpk5dOiQufnmm7PcXgsWLDDGGJOammp69OiRab8aNWqYU6dOWev+5ptvMvTx9PQ0VatWzfYk5Vm9pueeey7D+l0da46yM2G740Trme2v1atXGy8vrwzPX69ePZfryYttkVmNlzt58qTTBRC8vb3N6dOns9wuAHA943so4CzbI68AACgMEhJidf78IaWkSFOmSOlnKtlsaaOvUlJMjua+cuTr66vly5erTZs2KlGihMqXL6/XX39dr7/++lXXHRERoQEDBujmm29W6dKlVaRIEfn7+ysyMlKzZ8+2Rjk1adJECxYsUN26deXj46PatWvryy+/1B133OFyvY888ohiY2N1zz33KCgoSJ6enipbtqw6dOjgNMH4448/riFDhqhixYpOp7ZlpWTJklq3bp2GDh2q6tWry263q3jx4mrcuLH++9//6osvvrji/Fe5Ub58ea1bt04TJ05U27ZtVbp0aXl5ealcuXJq2bKlxo0bp9tvv11S2qlqX3zxhcaPH68mTZqoePHistvtqlatml588UWtW7fOaTTUHXfcoTFjxqhChQqy2+1q0qSJvvnmGzVv3jxPao+KitJjjz2mcuXK5cu2yUpkZKSWLl2qm2++Wd7e3qpUqZLGjBmjQYMGueyf39vCUcmSJdWlSxfr7w4dOlinpQIAANiM4Vy/rCQlJcnf31+JiYny8/Mr6HIAAFdw9OhMbdt2v779Vho5MuPyYcOk//s/qWbNLxQUxGlJwJQpU9SvXz9JaeHa8OHDC6SOzz//XH369JEkzZ49W927dy+QOgDA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t/o/9NBDma63V69eVr+cbOvsHMuOx9rltz59+mS5z8aNG+dy30gyvr6+Zv369VZfx/e5q2Pa19fXnDp1yhhjzMWLF021atUyrWvChAnZ3t8AAPfF91DAWY7H+F8+1wMA4NoICgrSv/71Ly1YsEATJ05UaGiofvzxR0nSI488ok8//TTDY3766Se98cYbkqSQkBCNGDFC5cuX19ixY7VkyRLFxsZq9OjRGjJkSIbHHjhwQFFRUbr11lv1+++/S0qb3+eXX36RlHYa+SuvvKKaNWtq165dWrx4scu6d+/erbffflvh4eEaMGCADh48qH379umbb76x5k/s0aOHevTooaCgIBUvXlxnzpzR7Nmz9fnnn2vbtm2aP3++7r///gzrPn78uMaPH68SJUqof//+SkhI0A8//KCtW7eqatWqio2N1VtvvaVly5ZJkj788EM1bNhQUs7mJ7LZbBnajDEZ2o4ePar3339fderU0d69eyVJTZo00dixYxUWFiZfX19dunRJGzdu1JAhQ3T27FmNHj3a5b67kpSUFA0aNMiqo2fPnnrwwQf13XffafTo0TleX07s2bNHzz77rDp27Kj9+/dbI/9GjRql8PBw+fv7q0iRIjpw4ICef/55HT9+XCNGjFDv3r0zrGv//v3q3LmzHnnkEc2YMUOzZs2SJH3yySdq27atpLSRg5IUFham9957T35+fjp48KC+//57+fn5WevKybbOzrE8duxYxcTE6Nlnn5UkdejQQcOGDZOU9n7MzMGDB6194+HhoWHDhikiIkJTpkzRl19+qeTkZPXt21e//fZbhmNrz549GjJkiJo3b65XXnlFmzdvVnJysr744gs9/fTT2r59u3bu3ClJatu2rZ5//nldunRJe/fu1dKlS2W323OwJwEAAAqHHIdXUVFR+VEHACAbHnnkES1YsECLFy+Wl5eXJKlevXpq3Lixy/4zZsyw7vfr10/VqlWTJD3xxBNasmSJJGn69Okuw6sXXnjBOkXtjjvuUGpqqtP8WjNnzrSuftiuXTv179/fZQ1PPfWUXnjhBUnSzp079eKLL0pKC7XStW3bVm+88Ya+++47HTlyROfPn3dax88//+wyvHr99df1+OOPS5LWrFmj8ePHW+uuXbu2WrRoobJly1r969atqxYtWrisMy+MHj1ajz76qFNbs2bNFBsbq08//VR/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RERERERE1P6YvNKWlBQgN7fh46IIXL9eXW/YsDbrVqwvWdZGZs2ahbfeeguHDx+Gr68vAgMD4enp2WD9zMxMlJaW1klKlZeXo1+/fmpltVdUEREREREREdHjg8krbcnLa9t6TeTi4gJBEJq9KbueXvX2aLWTXxUVFWp1pk+fDj8/P8TGxuLw4cOIiIjAmjVrEBISUm+bNb8EGBsbi65du6odk8lkao/ru8SxNjs7O9y6dUutrLKyEgUFBbCzs2v0XCIiIiIiIiLSXdywXVvs7du2XhNZW1vDz88PkZGRuHfvXp3jtTdkr83GxgYAkFcrmZaWllannlwux8yZMxETE4OwsDBs2bIFAGBoaAgAUKlUUt1evXpBJpMhJycHPXr0ULvJ5fJmjcvb2xuFhYX46aefpLJjx46hqqoKAwcObFZbRERERERERKQ7mLzSFh8foFu36r2t6iMIgFxeXa+NRUZGQqVSYcCAAdi7dy8uX76M9PR0rFu3Ttp76kE1CaXw8HBcvnwZsbGxWLNmjVqdOXPmID4+HllZWUhNTUViYiLc3d0BAI6OjhAEAQcOHMDt27dRUlICMzMzzJs3D6GhoYiOjsaVK1eQmpqK9evXIzo6ulljcnd3h7+/P2bMmIHTp0/jxIkTCA4OxoQJE9ClS5eWPVFEREREREREpHVMXmmLvj7w8cfV9x9MYNU8Xru2TTdrr6FQKJCamgqlUomwsDD07t0bw4cPR0JCAjZu3FjvOQYGBti5cycyMjLg6emJVatWYdmyZWp1VCoVgoKCpESSq6srNmzYAADo2rUrFi9ejPnz56Nz584IDg4GACxduhQLFy5ERESEdF5sbCycnZ2bPa4vvvgCbm5ueO655zBy5EgMGTIEn376abPbISIiIiIiIiLdIYia3MH7b6C4uBgWFhYoKiqCubm52rH79+8jKysLzs7OMDIyalkHMTHVvzpYe/N2ubw6cTVmTMsDp4dqk9ePiIiIiIiojTX2OZToccQN27VtzBggIKD6VwXz8qr3uPLx0ciKKyIiIiIiIiKiRw2TV7pAXx8YNkzbURARERERERER6RzueUVERERERERERDqLySsiIiIiIiIiItJZTF4REREREREREZHOYvKKiIiIiIiIiIh0FpNXRERERERERESks5i8IiIiIiIiIiIincXkFRERERERERER6Swmr6hB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b47ayRttJl4eVPu1OX36tHT/v//9r/ReTBAE9OjRo865D0tutVTt12LBggUICAjAkCFD6vwCYI2WPLcNjfuXX36Rfs3QysoKNjY2zYqdiIg0R6srr5rK3d0d/v7+mDFjBjZt2oSKigoEBwdjwoQJ0sbcN27cwHPPPYcdO3ZgwIABuHr1Kr766is8//zzsLGxQW5uLlauXAljY+NGN3BsL+V55W1ar6lcXFxadDlmzRuD2smvB5dxT58+HX5+foiNjcXhw4cRERGBNWvWICQkpN42S0pKAACxsbHSRp41HnzjWd8ljrUdO3YMJ0+erHOel5cXJk+erPYT1URERNQ6jo6OiIyMRH5+PsaOHdto3UmTJknbBYSGhqKgoACenp4oLCzElStXcPjwYTg6OmLbtm0P7VdPTw+TJk1CZGSk1PbChQvh5uaGq1ev4ttvv8XBgwdbNJ4a27Ztg0KhQGZmJpYtW9bstupTe7XO559/Dn19fejr62PIkCFt0n5LTZw4EevWrQMAfPLJJ+jSpQtcXFywdu1a6ctePz8/tcv+NK32a7Fu3ToYGhrihx9+wNatW+utX/u53bt3L5ydnWFgYICnnnqqwUTmpEmT8O233wIA/vOf/0Amk6FTp05YvHixVOell17SWIKOiIia75FIXgHAF198geDgYDz33HPQ09NDYGCg9McWqE6kXLp0Sfq2xMjICCkpKVi7di3u3LmDzp0745lnnsH3338PW1tbbQ1DYmhv2Kb1msra2hp+fn6IjIzErFmz6iSFCgsL6/32tOabp7y8POlNQlpaWp16crkcM2fOxMyZM/Hee+9hy5YtCAkJgaFh9ThUKpVUt1evXpDJZMjJyVG7RLAl1q1bp/YG87fffoOfnx+++uqrZq3OIyIioqaZOXNmk+oNGDAACxcuxNKlS1FYWIiwsLA6dV555ZUm97t8+XKkpKTg559/xu+//47Zs2dLx2onPppj1KhRsLe3R15eHs6ePSv9EuLgwYNx4sSJFrVZm1KpxIcffgigevVZVFQUAO1favb000/jnXfewfvvv4/79+9j7ty5asft7OywYcOGdo1pypQpWL58OUpLS3HkyBEcOXIEQMOvxbBhwyAIAkRRxMGDB6XkZVZWFpycnOrtY/z48di3bx+++uorFBQU1Nmzzc3NDStWrGjbgRERUas8Mskra2trfPnl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EmqJ8vJyAIC+PjfHJyIiIiIiItJV3LC9FfT19WFpaYlbt24BADp27AhBELQcFTVFVVUVbt++jY4dO6JDB/5vQERERERERKSr+Km9lezs7ABASmDRo0NPTw8ODg5MOBIRERERERHpMCavWkkQBNjb28PW1hYVFRXaDoeawdDQEHp6vHKWiIiIiIiISJcxedVG9PX1uXcSEREREREREVEb47ITIiIiIiIiIiLSWUxeERERERERERGRzmLyioiIiIiIiIiIdBb3vHoIURQBAMXFxVqOhIiIiIiIiB4HNZ8/az6PEj3umLx6iLt37wIA5HK5liMhIiIiIiKix8ndu3dhYWGh7TCItE4QmcptVFVVFX777TeYmZlBEARth/PIKi4uhlwux/Xr12Fubq7tcOgRw/lDrcH5Q63B+UMtxblDrcH5Q6Io4u7du+jSpQv09LjbDxFXXj2Enp4eunXrpu0w/jbMzc35B5hajPOHWoPzh1qD84dainOHWoPz5/HGFVdEf2EKl4iIiIiIiIiIdBaTV0REREREREREpLOYvKJ2IZPJsGjRIshkMm2HQo8gzh9qDc4fag3OH2opzh1qDc4fIiJ13LCdiIiIiIiIiIh0FldeERERERERERGRzmLyioiIiIiIiIiIdBaTV0REREREREREpLOYvCIiIiIiIiIiIp3F5BVpTEFBASZPngxzc3NYWlri9ddfR0lJSaPnvPnmm+jevTuMjY1hY2ODgIAAZGRktFPEpEuaO38KCgoQEhKCnj17wtjYGA4ODpg1axaKioraMWrSBS35t+fTTz/FsGHDYG5uDkEQUFhY2D7Bkk6IjIyEk5MTjIyMMHDgQJw+fbrR+l9//TXc3NxgZGSEPn364ODBg+0UKema5sydCxcuIDAwEE5OThAEAWvXrm2/QEknNWf+bNmyBT4+PrCysoKVlRV8fX0f+m8VEdHfCZNXpDGTJ0/GhQsXcOTIERw4cADJycl44403Gj2nf//+iIqKQnp6OuLj4yGKIp5//nmoVKp2ipp0RXPnz2+//YbffvsNq1evxi+//ILt27cjLi4Or7/+ejtGTbqgJf/2lJaWwt/fHwsWLGinKElXfPXVV5g7dy4WLVqE1NRU9O3bF35+frh161a99b///ntMnDgRr7/+Os6ePYvRo0dj9OjR+OWXX9o5ctK25s6d0tJSKBQKrFy5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yOVyyOVyqaxXr16wtLREeno6nnrqKQCAk5MTzMzMpDqdO3eGvr4+9PT01Mpu3bql1r63t3edx2lpaVLfffv2VVsZNnjwYFRVVeHSpUvo3LkzAMDDwwP6+vpSHXt7e5w/fx5A9WWHKpUKrq6uav2UlZXhiSeekB537NgR3bt3V2vjwViJiIiISHcweUVERNROlEolNm7cCENDQ3Tp0gUdOvz1Z9jV1RUZGRkPbaNmhdLAgQOlMlEUUVVVhV9//bVO4gYAXFxcIAhCk9pvCgMDA7XHgiDUW1ZVVdUm/T2s75p+SkpKoK+vj59++kktwQVUr6hqrI2mJviIiIiIqP3xskEiIqJ2YmJigh49esDBwUEtcQUAkyZNwq+//opvvvmmznmiKKKoqAhA9SWDYWFhSEtLk27nzp2Dj48Ptm3bVm+/1tbW8PPzQ2RkZL17YxUWFgIA3N3dcf36dVy/fl06dvHiRRQWFqJXr14tHbak9sbwNY/d3d2lvs+dO6cW34kTJ6Cnp9fkyyn79esHlUqFW7duoUePHmo3Ozu7JsdpaGgIlUrV5PpEREREpFlMXhEREemA8ePH46WXXsLEiROxYsUK/Pjjj7h27RoOHDgAX19fJCYmIi0tDampqZg+fTp69+6tdps4cSKio6NRWVlZb/uRkZFQqVQYMGAA9u7di8uXLyM9PR3r1q2TLufz9fVFnz59MHnyZKSmpuL06dOYOnUqhg4dCi8vr1aP8euvv8a2bdvw66+/YtGiRTh9+rS0IfvkyZNhZGSEV155Bb/88gsSExMREhKCl19+Wbpk8GFcXV0xefJkTJ06FTExMcjKysLp06cRERGB2NjYJsfp5OSEn3/+GZcuXcLvv/+u9muGtZWUlEgJRADIyspCWloacnJymtwXERERET0ck1dEREQ6QBAEfPnll/jwww+xf/9+DB06FJ6enggPD0dAQAD8/PywdetW9OrVq96N1//1r3/h1q1bOHjwYL3tKxQKpKamQqlUIiwsDL1798bw4cORkJCAjRs3SjF88803sLKywjPPPANfX18oFAp89dVXbTLGxYsXY9euXfD09MSOHTuwc+dOaUVXx44dER8fj4KCAjz11FMYO3YsnnvuOXzyySfN6iMqKgpTp05FWFgYevbsidGjR+PMmTNwcHBochszZsxAz5494eXlBRsbG5w4caLeej/++CP69euHfv36AQDmzp2Lfv364T//+U+zYiYiIiKixgkiN3kgIiIiDRMEAfv27cPo0aO1HQoRERERPWK48oqIiIiIiIiIiHQWk1dERERERERERKSzOjy8ChEREVHrcJcCIiIiImoprrwiIiIiIiIiIiKdxeQVERERERERERHpLCaviIiIiIiIiIhIZzF5RUREREREREREOovJKyIiIiIiIiIi0llMXhERERERERERkc5i8oqIiIiIiIiIiHQWk1dERERERERERKSzmLwiIiIiIiIiIiKd9f8BBXgOhLyIXRUAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ - "# Perform the analysis\n", - "summarized_issues, categorized_issues = analyze_negative_feedback_with_llm(conversation_data)\n", - "\n", - "# Print the summarized issues\n", - "# print(\"Summarized Issues:\")\n", - "# for summary in summarized_issues:\n", - "# print(summary)\n", - "\n", - "# Print categorized issues and identify incorrect information\n", - "print(\"\\nCategorized Issues:\")\n", - "for category, contents in categorized_issues.items():\n", - " print(f\"\\n{category}:\")\n", - " for content in contents:\n", - " print(f\" - {content}\")" + "clusters, main_themes = plot_kmeans_clusters(embeddings, feedbacks, optimal_cluster)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAB8UAAAPeCAYAAACV+su2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/TGe4hAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdeXhU5fk/4CegJMgSQCCAUlaLiAiKgjuoKCJaUYtgrSxVaa07rrRfWdQWsVVRa7VaBbTue13qhuKKIlq0rhUL4gKoKERAQcn5/eGV+TkmgQAJCSf3fV1zybzzznvec+Zk5uN5Zs7JSZIkCQAAAAAAAABIoVpVPQEAAAAAAAAAqCyK4gAAAAAAAACklqI4AAAAAAAAAKmlKA4AAAAAAABAaimKAwAAAAAAAJBaiuIAAAAAAAAApJaiOAAAAAAAAACppSgOAAAAAAAAQGopigMAAAAAAACQWoripErbtm1j+PDhVT0NNlH2n9INHz482rZtm9WWk5MT48aNq5L5rK+a9vpOnz49cnJyYvr06VWy/HHjxkVOTk6VLBuADVPTPjPTasqUKZGTkxOzZs2q6qlUumXLlsVxxx0XLVq0iJycnDjttNOqekoVRqYCIG1kTTZEnz59ok+fPlU9jY2uso/zbYrHemF9KIqzSXj//ffj17/+dbRv3z7y8vKiYcOGsccee8Tll18eX3/99UaZw4oVK2LcuHFVUmC6/vrro3PnzpGXlxfbbLNNXHnlles1TvGHZ3luafXCCy/EuHHjYsmSJVU9lYziA5bFt7y8vGjVqlX069cvrrjiivjqq6/We+y33norxo0bF/Pmzau4CadcTk5OnHTSSVU9jXL761//GlOmTKmSZVfl+yIA664mZ+qrr746Bg0aFD/5yU8iJyenQg7EFhcra9WqFR9++GGJxwsLC6Nu3bqbXLaoCJ988kmMGzcuZs+eXa7+G1rA/+Mf/xhTpkyJE044IW666aY45phj1mucqiJTAZAGNTVrfvjhhzF+/Pjo2bNnNG7cOJo2bRp9+vSJJ554Yr3GmzdvXrmP36b1eF91P5758MMPR05OTrRq1SqKioqqejrAOtisqicAa/PQQw/FoEGDIjc3N4YOHRrbb799rFq1Kp577rk466yz4s0334xrr7220uexYsWKGD9+fETERv022t/+9rf4zW9+E0cccUSMGjUqnn322TjllFNixYoVcc4556zTWJ07d46bbropq2306NFRv379+P3vf1+R0662XnjhhRg/fnwMHz48GjVqlPXYu+++G7VqVd13hc4///xo165dfPvtt7Fw4cKYPn16nHbaaXHppZfGP//5z9hhhx3Wecy33norxo8fH3369Cnxa+/yuu666wS8auyvf/1rNG3atMTB/b333ju+/vrrqFOnTqUte03vi//3f/8X5557bqUtG4B1U9Mz9cSJE+Orr76Knj17xoIFCyp07Nzc3Lj11lvj7LPPzmq/5557KnQ5m5JPPvkkxo8fH23bto3u3btX+vKefPLJ2HXXXWPs2LGVvqzKIFMBsKmryVnz/vvvj4kTJ8bAgQNj2LBh8d1338WNN94Y+++/f9xwww0xYsSIdRqvWbNmJY7fXnLJJfHRRx/FZZddVqJvGq3peOZjjz1WNZP6gZtvvjnatm0b8+bNiyeffDL69u1b1VPaYF9//XVstplyIelnL6damzt3bgwZMiTatGkTTz75ZLRs2TLz2Iknnhhz5syJhx56qApnuOGWL18e9erVK/Wxr7/+On7/+9/HgAED4q677oqIiOOPPz6KioriggsuiJEjR0bjxo3LvayCgoL45S9/mdV20UUXRdOmTUu0/1BRUVGsWrUq8vLyyr2sTVFubm6VLr9///6x8847Z+6PHj06nnzyyTj44IPjZz/7Wbz99ttRt27djT6vzTfffKMvkw1Xq1atKv2b3WyzzYRpgGqipmfqiIinn3468yvx+vXrV+iyDzrooFKL4rfccksMGDAg7r777gpbVk3J5evq008/je22267Cxvvuu++iqKioUr9cWF4yFQDVXU3Pmvvss0/Mnz8/mjZtmmn7zW9+E927d48xY8asc1G8Xr16JY7T3nbbbfHll1+u8fhtkiTxzTffVMmxw42pqvPZ8uXL4/77748JEybE5MmT4+abb05FUdz/X1BTOH061drFF18cy5Yti+uvvz4rUBXr2LFjnHrqqWU+v6zrrxWfnu+Hp2CZNWtW9OvXL5o2bRp169aNdu3axa9+9auI+P60NcXfvBs/fnzmFDU/vM7GO++8Ez//+c+jSZMmkZeXFzvvvHP885//LHW5Tz/9dPz2t7+N5s2bx9Zbb13m/J966qlYvHhx/Pa3v81qP/HEE2P58uVZgXLFihXxzjvvxOeff17meOVVfIrHm2++Obp06RK5ubnxyCOPRETEn//859h9991jyy23jLp160aPHj0yBfvSxrjvvvti++23j9zc3OjSpUtmnGJfffVVnHbaadG2bdvIzc2N5s2bx/777x+vvvpqps+zzz6bOd1lbm5utG7dOk4//fRST730zjvvxJFHHhnNmjWLunXrRqdOnTK/gh83blycddZZERHRrl27EqcaKu2aRv/73/9i0KBB0aRJk9hiiy1i1113LRHki09Lf8cdd8Qf/vCH2HrrrSMvLy/222+/mDNnzrpt/B/Zd99947zzzosPPvgg/vGPf5RY1zXtc1OmTIlBgwZFxPcBvXh9i08hdf/998eAAQOiVatWkZubGx06dIgLLrggVq9enbWc0q4p/mPleR1L88EHH8Rvf/vb6NSpU9StWze23HLLGDRoUInTIxX/7Tz//PMxatSoaNasWdSrVy8OO+yw+Oyzz7L6JkkSF154YWy99daxxRZbxD777BNvvvnmGuexJuV9fU866aSoX79+rFixosQYRx11VLRo0SJr2/7rX/+KvfbaK+rVqxcNGjSIAQMGlJjnwoULY8SIEbH11ltHbm5utGzZMg499NCsffbNN9+Mp59+OvP6Fn8TuqxrDV111VXRvn37qFu3bvTs2TOeffbZEtdjWrVqVYwZMyZ69OgR+fn5Ua9evdhrr73iqaeeyvRZ2/tiae+/3333XVxwwQXRoUOHyM3NjbZt28bvfve7WLlyZVa/tm3bxsEHHxzPPfdc9OzZM/Ly8qJ9+/Zx4403lv1CAVCmmp6pIyLatGlTrksEffvtt/HOO++s06/Jf/GLX8Ts2bPjnXfeybQtXLgwnnzyyfjFL35R6nNWrlwZY8eOjY4dO2by7dlnn13iM3FNufzjjz+OY489NpPl2rVrFyeccEKsWrWqxLLWlp/Kmwv79OkT22+/fbz11luxzz77xBZbbBFbbbVVXHzxxZk+06dPj1122SUiIkaMGJF5ndf1ci/Dhw+P+vXrx8cffxwDBw6M+vXrR7NmzeLMM8/MzKs478ydOzceeuihEvn+008/jWOPPTYKCgoiLy8vunXrFlOnTs1aTvEpSv/85z/HpEmTMjml+LSdOTk58d///jd++ctfRn5+fjRr1izOO++8SJIkPvzwwzj00EOjYcOG0aJFi7jkkkuyxpapAKgJanrW7NKlS1ZBPOL7H94cdNBB8dFHH2VdFnF9smZZij/nH3300dh5552jbt268be//S0iIiZPnhz77rtvNG/ePHJzc2O77baLq6++uswx1pYVvv322xg/fnxss802kZeXF1tuuWXsueee8fjjj2f6vP766zF8+PDM6fNbtGgRv/rVr2Lx4sUllrumHLu245mlXVN8XTPftddem8lRu+yyS7z88svl3u733ntvfP311zFo0KAYMmRI3HPPPfHNN9+U6FfeY+PlPTb6Y2PHjo3NN9+8RK6PiBg5cmQ0atQoM681/d38cL4//FtZ32O9UN35ujHV2gMPPBDt27eP3XffvVKX8+mnn8YBBxwQzZo1i3PPPTcaNWoU8+bNy5zysFmzZnH11VfHCSecEIcddlgcfvjhERGZ01m/+eabsccee8RWW20V5557btSrVy/uuOOOGDhwYNx9991x2GGHZS3vt7/9bTRr1izGjBkTy5cvL3Ne//73vyMisn49HBHRo0ePqFWrVvz73//OfENw5syZsc8++8TYsWOzPsDW15NPPhl33HFHnHTSSdG0adNMUfTyyy+Pn/3sZ3H00UfHqlWr4rbbbotBgwbFgw8+GAMGDMga47nnnot77rknfvvb30aDBg3iiiuuiCOOOCLmz58fW265ZUR8/83Ju+66K0466aTYbrvtYvHixfHcc8/F22+/HTvttFNERNx5552xYsWKOOGEE2LLLbeMmTNnxpVXXhkfffRR3HnnnZnlvf7667HXXnvF5ptvHiNHjoy2bdvG+++/Hw888ED84Q9/iMMPPzz++9//xq233hqXXXZZJrCWdaqhRYsWxe677x4rVqyIU045JbbccsuYOnVq/OxnP4u77rqrxOt60UUXRa1ateLMM8+MpUuXxsUXXxxHH310vPTSSxv0WhxzzDHxu9/9Lh577LE4/vjjI6J8+9zee+8dp5xySlxxxRXxu9/9Ljp37hwRkfnvlClTon79+jFq1KioX79+PPnkkzFmzJgoLCyMP/3pT+s0x/K8jqV5+eWX44UXXoghQ4bE1ltvHfPmzYurr746+vTpE2+99VZsscUWWf1PPvnkaNy4cYwdOzbmzZsXkyZNipNOOiluv/32TJ8xY8bEhRdeGAcddFAcdNBB8eqrr8YBBxxQ4gDxulrb6zt48OC46qqrMqcMK7ZixYp44IEHYvjw4VG7du2IiLjpppti2LBh0a9fv5g4cWKsWLEirr766thzzz3j3//+d+bv7Ygjjog333wzTj755Gjbtm18+umn8fjjj8f8+fOjbdu2MWnSpDj55JOzLoFQUFBQ5jpcffXVcdJJJ8Vee+0Vp59+esybNy8GDhwYjRs3zvofvMLCwvj73/8eRx11VBx//PHx1VdfxfXXXx/9+vWLmTNnRvfu3df6vlia4447LqZOnRo///nP44wzzoiXXnopJkyYEG+//Xbce++9WX3nzJkTP//5z+PYY4+NYcOGxQ033BDDhw+PHj16RJcuXdbhlQOgpmfqdfHxxx9H586dY9iwYeUu4u69996x9dZbxy233BLnn39+RETcfvvtUb9+/RL5OOL7X3v/7Gc/i+eeey5GjhwZnTt3jv/85z9x2WWXxX//+9+47777svqXlss/+eST6NmzZyxZsiRGjhwZ2267bXz88cdx1113xYoVK7J+QVOe/LQuufDLL7+MAw88MA4//PA48sgj46677opzzjknunbtGv3794/OnTvH+eefH2PGjImRI0fGXnvtFRGxXvvf6tWro1+/ftGrV6/485//HE888URccskl0aFDhzjhhBMyl4c6/fTTY+utt44zzjgjIr7f177++uvo06dPzJkzJ0466aRo165d3HnnnTF8+PBYsmRJiYPzkydPjm+++SZGjhwZubm50aRJk8xjgwcPjs6dO8dFF10UDz30UFx44YXRpEmT+Nvf/hb77rtvTJw4MW6++eY488wzY5dddom99947ImQqAGoGWbN0CxcujC222CLr2Nb6ZM01effdd+Ooo46KX//613H88cdHp06dIuL74z9dunSJn/3sZ7HZZpvFAw88EL/97W+jqKgoTjzxxKwxypMVxo0bFxMmTIjjjjsuevbsGYWFhTFr1qx49dVXY//994+IiMcffzz+97//xYgRI6JFixaZU+a/+eab8eKLL2a++LC2HLu245k/tq6Z75Zbbomvvvoqfv3rX0dOTk5cfPHFcfjhh8f//ve/cp0t8+abb4599tknWrRoEUOGDIlzzz03HnjggaxjgcXKc2x8XY+NFjvmmGPi/PPPj9tvvz1OOumkTPuqVavirrvuiiOOOCLy8vLW+ndTlvU91gvVXgLV1NKlS5OISA499NByP6dNmzbJsGHDMvfHjh2blLabT548OYmIZO7cuUmSJMm9996bRETy8ssvlzn2Z599lkREMnbs2BKP7bfffknXrl2Tb775JtNWVFSU7L777sk222xTYrl77rln8t133611fU488cSkdu3apT7WrFmzZMiQIZn7Tz31VJnzW5MuXbokvXv3zmqLiKRWrVrJm2++WaL/ihUrsu6vWrUq2X777ZN99923xBh16tRJ5syZk2l77bXXkohIrrzyykxbfn5+cuKJJ65xjj9eZpIkyYQJE5KcnJzkgw8+yLTtvffeSYMGDbLakuT716LYn/70p6zX/od+vP+cdtppSUQkzz77bKbtq6++Stq1a5e0bds2Wb16dZIk/3/bd+7cOVm5cmWm7+WXX55ERPKf//xnjetXvF+saf/Lz89Pdtxxx8z98u5zd955ZxIRyVNPPVVizNK2669//etkiy22yBp32LBhSZs2bbL6/XhfK8/rWJrS5jBjxowkIpIbb7wx01a8jfr27Zv1ep5++ulJ7dq1kyVLliRJkiSffvppUqdOnWTAgAFZ/X73u98lEZH1+pYlIrLWpbyvb1FRUbLVVlslRxxxRNZ4d9xxRxIRyTPPPJMkyff7UKNGjZLjjz8+q9/ChQuT/Pz8TPuXX36ZRETypz/9aY3zLe1v+IfzLn7tV65cmWy55ZbJLrvsknz77beZflOmTEkiImuM7777Lmtdi+dTUFCQ/OpXv8q0rel98cfvv7Nnz04iIjnuuOOy+p155plJRCRPPvlkpq1NmzZZ2yxJvn9tc3NzkzPOOGON2wOAbDJ1SfXq1SszE8ydO7fcmaF4u3z22WfJmWeemXTs2DHz2C677JKMGDEiSZKS2eKmm25KatWqlZUxkyRJrrnmmiQikueffz7TVlYuHzp0aFKrVq1St3VxBipvfkqS8ufC3r17l8hpK1euTFq0aJGVgV5++eUkIpLJkyeXGLc0peXhYcOGJRGRnH/++Vl9d9xxx6RHjx5ZbW3atEkGDBiQ1TZp0qQkIpJ//OMfmbZVq1Ylu+22W1K/fv2ksLAwSZL//5o3bNgw+fTTT7PGKH6NR44cmWn77rvvkq233jrJyclJLrrookz7l19+mdStWzdr35GpAEg7WbN07733XpKXl5ccc8wxWe3rkjV/aMCAASWOzRV/zj/yyCMl+peW7fr165e0b9++1DHWlhW6detWImuVZ5m33nprifHLk2PXdDyzd+/eWcew1jXzbbnllskXX3yR6Xv//fcnEZE88MADa1y/JEmSRYsWJZtttlly3XXXZdp23333Uvf/8h4bL++x0R8f50uSJNltt92SXr16ZT33nnvuyepXnr+b4vlWxLFeqO6cPp1qq7CwMCIiGjRoUOnLatSoUUREPPjgg/Htt9+u03O/+OKLePLJJ+PII4+Mr776Kj7//PP4/PPPY/HixdGvX79477334uOPP856zvHHH5/5xeiafP3112VeJyUvLy/r9OF9+vSJJEkq5FfiERG9e/cu9bp8P7wuzZdffhlLly6Nvfbaq9RTp/Tt2zc6dOiQub/DDjtEw4YN43//+1+mrVGjRvHSSy/FJ598UuZcfrjM5cuXx+effx677757JEmS+TX9Z599Fs8880z86le/ip/85CdZzy/PqTJL8/DDD0fPnj1jzz33zLTVr18/Ro4cGfPmzYu33norq/+IESOyXq/iX8X8cH3XV/369TOnW1qffa40P9yuxePstddemVPxr4vyvI5rm8O3334bixcvjo4dO0ajRo1K3adGjhyZ9XrutddesXr16vjggw8iIuKJJ56IVatWxcknn5zV77TTTluneZVmba9vTk5ODBo0KB5++OFYtmxZpt/tt98eW221VWY/evzxx2PJkiVx1FFHZV67zz//PGrXrh29evXKnE6zbt26UadOnZg+fXp8+eWXGzz/WbNmxeLFi+P444/Pui7l0UcfHY0bN87qW7t27cy6FhUVxRdffBHfffdd7Lzzzut9mqSHH344IiJGjRqV1V78i64fX5Zgu+22y2zjiO+/8d2pU6cK+XsCqElk6nXTtm3bSJJknX+584tf/CLmzJkTL7/8cua/ZZ06/c4774zOnTvHtttum5UF9t1334iIrFNrR5TM5UVFRXHffffFIYccUuKMUhEls+/a8lPEuuXC+vXrZ13Psk6dOtGzZ89K+4z+zW9+k3V/r732KteyHn744WjRokUcddRRmbbNN988TjnllFi2bFk8/fTTWf2POOKIMs8gddxxx2X+Xbt27dh5550jSZI49thjM+2NGjUqkVVkKgDSTtYsacWKFTFo0KCoW7duXHTRRVmPrW/WLEu7du2iX79+Jdp/mO2WLl0an3/+efTu3Tv+97//xdKlS7P6licrNGrUKN5888147733ypzLD5f5zTffxOeffx677rprREQm96xrji2Pdc18gwcPzjoOti7Hb2+77baoVatWHHHEEZm2o446Kv71r3+VeuyuPMfG1/XY6A8NHTo0XnrppXj//fczbTfffHO0bt06evfuHRHr/3ezvsd6obpTFKfaatiwYURE1nVXKkvv3r3jiCOOiPHjx0fTpk3j0EMPjcmTJ5e4Jltp5syZE0mSxHnnnRfNmjXLuo0dOzYivj+9zw+1a9euXPOqW7dumad8/uabb7I+NCtaWXN88MEHY9ddd428vLxo0qRJ5tREPw5UEVGiOB0R0bhx46yQcPHFF8cbb7wRrVu3jp49e8a4ceNKhJD58+fH8OHDo0mTJplrCRZ/sBcvt/g522+//fqtcCk++OCDzGmHfqj4dD0/PJAYUXJ9iwNWRRQ0ly1blvkfjPXZ50rz5ptvxmGHHRb5+fnRsGHDaNasWeYAZ2mv55qU53Uszddffx1jxoyJ1q1bR25ubjRt2jSaNWsWS5YsKdc+9eNtXPyabLPNNln9mjVrVqLwu67K8/oOHjw4vv7668z1qJYtWxYPP/xwDBo0KBPsi/8HYt999y3x+j322GOZ1y43NzcmTpwY//rXv6KgoCD23nvvuPjii2PhwoXrNf/ibdOxY8es9s0226zUa8ZPnTo1dthhh8y1opo1axYPPfTQOu8bP1x+rVq1Siy/RYsW0ahRo7X+PUWUfP8AYO1k6o1jxx13jG233TZuueWWuPnmm6NFixaZIvePvffee/Hmm2+WWM+f/vSnEbH29fzss8+isLCw3Lm3PBlmXXLh1ltvXeKAZWV9Rufl5ZUoVJd3WR988EFss802UatW9mGPsrL8mvanH2/D/Pz8yMvLK3H90Pz8/BJzk6kASDNZM9vq1atjyJAh8dZbb8Vdd90VrVq1Wucx1kVZc3z++eejb9++Ua9evWjUqFE0a9Ysfve730VEyWxXnqxw/vnnx5IlS+KnP/1pdO3aNc4666x4/fXXs57zxRdfxKmnnhoFBQVRt27daNasWWZ+xctc1xxbHuua+Tbk+O0//vGP6NmzZyxevDjmzJkTc+bMiR133DFWrVqVdYnPspZVvLwfLmtdj43+0ODBgyM3NzduvvnmiPh+Oz/44INx9NFHZ/L6+v7drO+xXqjuXFOcaqthw4bRqlWreOONN9Z7jLK+XbZ69eoS/e6666548cUX44EHHohHH300fvWrX8Ull1wSL774YtSvX7/MZRQVFUVExJlnnlnqN/MiShahylvMbtmyZaxevTo+/fTTaN68eaZ91apVsXjx4koNVqXN8dlnn42f/exnsffee8df//rXaNmyZWy++eYxefLkuOWWW0r0L+vblEmSZP595JFHxl577RX33ntvPPbYY/GnP/0pJk6cGPfcc0/0798/Vq9eHfvvv3988cUXcc4558S2224b9erVi48//jiGDx+e2f7VQXnWd3189NFHsXTp0sx+tD773I8tWbIkevfuHQ0bNozzzz8/OnToEHl5efHqq6/GOeecs87bdW2vY1lOPvnkmDx5cpx22mmx2267RX5+fuTk5MSQIUNKnUNlbePyKM+yd91112jbtm3ccccd8Ytf/CIeeOCB+Prrr2Pw4MGZPsXrddNNN0WLFi1KjPfDX3Gfdtppccghh8R9990Xjz76aJx33nkxYcKEePLJJ2PHHXesqFUr4R//+EcMHz48Bg4cGGeddVY0b948ateuHRMmTMj69un6KO+3fqvytQZIE5l64/nFL34RV199dTRo0CAGDx5c4sBcsaKioujatWtceumlpT7eunXrrPsbup5r+0xd11y4MT+jK/pMAGuypu1c2jzKsx1kKgDSTtbMdvzxx8eDDz4YN998c5lfkKxIpc3x/fffj/322y+23XbbuPTSS6N169ZRp06dePjhh+Oyyy5br2y39957x/vvvx/3339/PPbYY/H3v/89LrvssrjmmmsyZ9Q58sgj44UXXoizzjorunfvHvXr14+ioqI48MADU3H89r333ouXX345Ikr+GCfi+19ojxw5cp2Xta7HRn+ocePGcfDBB8fNN98cY8aMibvuuitWrlyZdVan9f27Wd9jvVDdKYpTrR188MFx7bXXxowZM2K33XZb5+cXf9NryZIlmVOFRJT8hlixXXfdNXbdddf4wx/+ELfcckscffTRcdttt8Vxxx1XZkBr3759RHx/Wpa+ffuu8xzXpHv37hHx/WmPDzrooEz7rFmzoqioKPP4xnL33XdHXl5ePProo5Gbm5tpnzx58gaN27Jly/jtb38bv/3tb+PTTz+NnXbaKf7whz9E//794z//+U/897//jalTp8bQoUMzz3n88cezxih+HdYWwtflNDxt2rSJd999t0R78Skk27RpU+6xNsRNN90UEZEJ7euyz5W1vtOnT4/FixfHPffcE3vvvXemfe7cues9zzW9jmW56667YtiwYXHJJZdk2r755ptYsmTJes2h+DV57733Mtsp4vtvom6sX8MceeSRcfnll0dhYWHcfvvt0bZt28zpoiIic9qk5s2bl+s9o0OHDnHGGWfEGWecEe+991507949LrnkkvjHP/4REeXfp4u3zZw5c2KfffbJtH/33Xcxb9682GGHHTJtd911V7Rv3z7uueeerPGLvz1dbF3/noqKiuK9997LfFs3ImLRokWxZMmSjfb3BFAT1fRMvbH84he/iDFjxsSCBQsy+a00HTp0iNdeey3222+/9TpFZLNmzaJhw4YbdPD5hyojF67v5YsqUps2beL111+PoqKirC8obMwsL1MBUBPImt8766yzYvLkyTFp0qSsU3lvbA888ECsXLky/vnPf2b9UvnHl+hZV02aNIkRI0bEiBEjYtmyZbH33nvHuHHj4rjjjosvv/wypk2bFuPHj48xY8ZknvPj062XN8euazbaGJnv5ptvjs033zxuuummEsXu5557Lq644oqYP39+qb8OX5MNPTY6dOjQOPTQQ+Pll1+Om2++OXbcccfo0qVLiX5r+rspy/oc64XqzunTqdbOPvvsqFevXhx33HGxaNGiEo+///77cfnll5f5/OLi0zPPPJNpW758eUydOjWr35dfflni22DFBefiU4lsscUWERElPpCaN28effr0ib/97W+xYMGCEnP47LPPypzf2uy7777RpEmTuPrqq7Par7766thiiy1iwIABmbbi6/19/vnn6728taldu3bk5ORkfVNz3rx5cd99963XeKtXry5xGpjmzZtHq1atMtu9OGT88PVJkqTE696sWbPYe++944Ybboj58+dnPfbD59arVy8iSr6OpTnooINi5syZMWPGjEzb8uXL49prr422bduWes31ivbkk0/GBRdcEO3atYujjz46ItZtnytrfUvbrqtWrYq//vWv6zzH8ryOZaldu3aJv70rr7yyxLeBy6tv376x+eabx5VXXpk17qRJk9ZrvPUxePDgWLlyZUydOjUeeeSROPLII7Me79evXzRs2DD++Mc/lnotn+LXb8WKFfHNN99kPdahQ4do0KBB1natV69eufbnnXfeObbccsu47rrr4rvvvsu033zzzSW+MFDa/vHSSy9l/S1ElP2+WJriL/b8+LUo/pXcD9/PAKhYNT1Tr4tvv/023nnnnVLnsDYdOnSISZMmxYQJE6Jnz55l9jvyyCPj448/juuuu67EY19//XUsX758jcupVatWDBw4MB544IGYNWtWicfX9RfAFZkLi61L5q4sBx10UCxcuDBuv/32TNt3330XV155ZdSvXz9zOabKJFMBUBPImhF/+tOf4s9//nP87ne/i1NPPbXMfhuSNcurtPyxdOnSDfpR0+LFi7Pu169fPzp27LjG47cRJfNKeXPsuh6/3RiZ7+abb4699torBg8eHD//+c+zbmeddVZERNx6663rPO6GHhvt379/NG3aNCZOnBhPP/101q/EI8r3d/NjG3KsF6o7vxSnWuvQoUPccsstMXjw4OjcuXMMHTo0tt9++1i1alW88MILceedd8bw4cPLfP4BBxwQP/nJT+LYY4+Ns846K2rXrh033HBDNGvWLKtwOnXq1PjrX/8ahx12WHTo0CG++uqruO6666Jhw4aZgw5169aN7bbbLm6//fb46U9/Gk2aNIntt98+tt9++7jqqqtizz33jK5du8bxxx8f7du3j0WLFsWMGTPio48+itdee2291r9u3bpxwQUXxIknnhiDBg2Kfv36xbPPPhv/+Mc/4g9/+EM0adIk03fmzJmxzz77xNixY2PcuHHrtby1GTBgQFx66aVx4IEHxi9+8Yv49NNP46qrroqOHTuWuI5MeXz11Vex9dZbx89//vPo1q1b1K9fP5544ol4+eWXM9+O23bbbaNDhw5x5plnxscffxwNGzaMu+++u9Rf/V5xxRWx5557xk477RQjR46Mdu3axbx58+Khhx6K2bNnR0REjx49IiLi97//fQwZMiQ233zzOOSQQzJh64fOPffcuPXWW6N///5xyimnRJMmTWLq1Kkxd+7cuPvuu8s8Jeb6+te//hXvvPNOfPfdd7Fo0aJ48skn4/HHH482bdrEP//5z8jLy8v0Le8+171796hdu3ZMnDgxli5dGrm5ubHvvvvG7rvvHo0bN45hw4bFKaecEjk5OXHTTTet12kUy/M6luXggw+Om266KfLz82O77baLGTNmxBNPPBFbbrnlOs8j4vsvR5x55pkxYcKEOPjgg+Oggw6Kf//73/Gvf/2rxDUfK8tOO+0UHTt2jN///vexcuXKrFOnR3x/arGrr746jjnmmNhpp51iyJAhmfekhx56KPbYY4/4y1/+Ev/9739jv/32iyOPPDK222672GyzzeLee++NRYsWxZAhQzLj9ejRI66++uq48MILo2PHjtG8efNST9FVp06dGDduXJx88smx7777xpFHHhnz5s2LKVOmRIcOHbK+hXvwwQfHPffcE4cddlgMGDAg5s6dG9dcc01st912sWzZsky/Nb0v/li3bt1i2LBhce2112ZO0zpz5syYOnVqDBw4MOvX6wBUrJqeqSO+/8VM8fO//fbbeP311+PCCy+MiIif/exnmTOmfPzxx9G5c+cYNmxYTJkyZZ2Xs6aDoMWOOeaYuOOOO+I3v/lNPPXUU7HHHnvE6tWr45133ok77rgjHn300dh5553XOMYf//jHeOyxx6J3794xcuTI6Ny5cyxYsCDuvPPOeO6557J+ZbU2FZkLi3Xo0CEaNWoU11xzTTRo0CDq1asXvXr12qjXgR85cmT87W9/i+HDh8crr7wSbdu2jbvuuiuef/75mDRpUjRo0KDS5yBTAVAT1PSsee+998bZZ58d22yzTXTu3DlzZr9i+++/fxQUFETEhmfN8jjggAOiTp06ccghh8Svf/3rWLZsWVx33XXRvHnz9S7Gb7fddtGnT5/o0aNHNGnSJGbNmhV33XVXnHTSSRHx/bGuvffeOy6++OL49ttvY6uttorHHnus1DMPlSfHlnU884eXFy22MTLfSy+9FHPmzMms749ttdVWsdNOO8XNN98c55xzzjqNvaHHRjfffPMYMmRI/OUvf4natWuXOEtBef5ufmxDjvVCtZfAJuC///1vcvzxxydt27ZN6tSpkzRo0CDZY489kiuvvDL55ptvMv3atGmTDBs2LOu5r7zyStKrV6+kTp06yU9+8pPk0ksvTSZPnpxERDJ37twkSZLk1VdfTY466qjkJz/5SZKbm5s0b948Ofjgg5NZs2ZljfXCCy8kPXr0SOrUqZNERDJ27NjMY++//34ydOjQpEWLFsnmm2+ebLXVVsnBBx+c3HXXXZk+xct9+eWX12n9r7322qRTp05JnTp1kg4dOiSXXXZZUlRUlNXnqaeeKjGn8ujSpUvSu3fvrLaISE488cRS+19//fXJNttsk+Tm5ibbbrttMnny5GTs2LHJj99Oyhrjh6/RypUrk7POOivp1q1b0qBBg6RevXpJt27dkr/+9a9Zz3nrrbeSvn37JvXr10+aNm2aHH/88clrr72WREQyefLkrL5vvPFGcthhhyWNGjVK8vLykk6dOiXnnXdeVp8LLrgg2WqrrZJatWpl7Qel7T/vv/9+8vOf/zwzXs+ePZMHH3wwq0/xtr/zzjuz2ufOnVvqHH+seL8ovtWpUydp0aJFsv/++yeXX355UlhYWOrzyrPPJUmSXHfddUn79u2T2rVrJxGRPPXUU0mSJMnzzz+f7LrrrkndunWTVq1aJWeffXby6KOPZvVJkiQZNmxY0qZNm6wxf7ivlfd1LM2XX36ZjBgxImnatGlSv379pF+/fsk777xT4rUo62+neNv/cL6rV69Oxo8fn7Rs2TKpW7du0qdPn+SNN94o9fUtzY/33fV5fX//+98nEZF07NixzOU89dRTSb9+/ZL8/PwkLy8v6dChQzJ8+PDM+87nn3+enHjiicm2226b1KtXL8nPz0969eqV3HHHHVnjLFy4MBkwYEDSoEGDJCIyf8+lbZskSZIrrrgiadOmTZKbm5v07Nkzef7555MePXokBx54YKZPUVFR8sc//jHTb8cdd0wefPDBUveFst4XS3tf+Pbbb5Px48cn7dq1SzbffPOkdevWyejRo7Pex5Pk+7/FAQMGlNhmvXv3LvF+BUD51eRMPWzYsKy89cPbDz/Liz/fy5MZij/rPvvsszX2Ky0Xr1q1Kpk4cWLSpUuXJDc3N2ncuHHSo0ePZPz48cnSpUvX+NxiH3zwQTJ06NCkWbNmSW5ubtK+ffvkxBNPTFauXJkkybrlp/Lmwt69eyddunQpMZfSMsL999+fbLfddslmm2221kxc2lyHDRuW1KtXr0Tf0jJGWdlh0aJFmaxZp06dpGvXriXmUfya/+lPfypzWT9+jcua24+3j0wFQE1SU7Nm8Wd1WbcfZql1yZo/NGDAgBLZoazP+SRJkn/+85/JDjvskOTl5SVt27ZNJk6cmNxwww1Z23NNY/w4K1x44YVJz549k0aNGiV169ZNtt122+QPf/hDsmrVqkyfjz76KHNMNj8/Pxk0aFDyySeflHq8em05NknKPp5ZWo7Z0My3tmPqJ598chIRyfvvv19mn3HjxiURkbz22muZMdd2bDxJyn9stKzjfEmSJDNnzkwiIjnggANKPFbev5uKOtYL1V1OkmzA178BgE1aUVFRNGvWLA4//PBST+MKAAAAAFRPr732WnTv3j1uvPHGOOaYY6p6OlCtuaY4ANQQ33zzTYlTod54443xxRdfRJ8+fapmUgAAAADAernuuuuifv36cfjhh1f1VKDac01xAKghXnzxxTj99NNj0KBBseWWW8arr74a119/fWy//fYxaNCgqp4eAAAAAFAODzzwQLz11ltx7bXXxkknnRT16tWr6ilBtef06QBQQ8ybNy9OOeWUmDlzZnzxxRfRpEmTOOigg+Kiiy6K5s2bV/X0AAAAAIByaNu2bSxatCj69esXN910UzRo0KCqpwTVnqI4AAAAAAAAAKnlmuIAAAAAAAAApJaiOAAAAAAAAACptVlVT6A6Kioqik8++SQaNGgQOTk5VT0dAIBqJUmS+Oqrr6JVq1ZRq5bvWK6JXAkAUDqZsvxkSgCAspU3VyqKl+KTTz6J1q1bV/U0AACqtQ8//DC23nrrqp5GtSZXAgCsmUy5djIlAMDarS1XKoqXokGDBhHx/cZr2LBhFc8GAKB6KSwsjNatW2cyE2WTKwEASidTlp9MCQBQtvLmSkXxUhSfhqhhw4aCJgBAGZy6ce3kSgCANZMp106mBABYu7XlShfsAQAAAAAAACC1FMUBAAAAAAAASC1FcQAAAAAAAABSS1EcAAAAAAAAgNRSFAcAAAAAAAAgtRTFAQAAAAAAAEgtRXEAAAAAAAAAUktRHAAAAAAAAIDUUhQHAAAAAAAAILUUxQEAAAAAAABILUVxAAAAAAAAAFJLURwAAAAAAACA1KrSoviECRNil112iQYNGkTz5s1j4MCB8e677671eXfeeWdsu+22kZeXF127do2HH3446/EkSWLMmDHRsmXLqFu3bvTt2zfee++9yloNAACqkEwJAEBFkCsBANKrSoviTz/9dJx44onx4osvxuOPPx7ffvttHHDAAbF8+fIyn/PCCy/EUUcdFccee2z8+9//joEDB8bAgQPjjTfeyPS5+OKL44orrohrrrkmXnrppahXr17069cvvvnmm42xWgAAbEQyJQAAFUGuBABIr5wkSZKqnkSxzz77LJo3bx5PP/107L333qX2GTx4cCxfvjwefPDBTNuuu+4a3bt3j2uuuSaSJIlWrVrFGWecEWeeeWZERCxdujQKCgpiypQpMWTIkLXOo7CwMPLz82Pp0qXRsGHDilk5AICUqO5Zqbpkyojqv60AAKrKppCTqkuu3BS2FQBAVSlvVqpW1xRfunRpREQ0adKkzD4zZsyIvn37ZrX169cvZsyYERERc+fOjYULF2b1yc/Pj169emX6AACQXjIlAAAVQa4EAEiPzap6AsWKioritNNOiz322CO23377MvstXLgwCgoKstoKCgpi4cKFmceL28rq82MrV66MlStXZu4XFhau1zoAAFC1qjJTRsiVAABp4VglAEC6VJui+IknnhhvvPFGPPfccxt92RMmTIjx48dv9OVCTZYzPqeqp0DKJWOrzdVBgI2oKjNlhFwJVUGupDLJlFBzOVYJNYtMSWWTK6HqVYvTp5900knx4IMPxlNPPRVbb731Gvu2aNEiFi1alNW2aNGiaNGiRebx4ray+vzY6NGjY+nSpZnbhx9+uL6rAgBAFanqTBkhVwIApEFV50qZEgCg4lVpUTxJkjjppJPi3nvvjSeffDLatWu31ufstttuMW3atKy2xx9/PHbbbbeIiGjXrl20aNEiq09hYWG89NJLmT4/lpubGw0bNsy6AQCwaagumTJCrgQA2JRVl1wpUwIAVLwqPX36iSeeGLfcckvcf//90aBBg8x1dPLz86Nu3boRETF06NDYaqutYsKECRERceqpp0bv3r3jkksuiQEDBsRtt90Ws2bNimuvvTYiInJycuK0006LCy+8MLbZZpto165dnHfeedGqVasYOHBglawnAACVR6YEAKAiyJUAAOlVpUXxq6++OiIi+vTpk9U+efLkGD58eEREzJ8/P2rV+v8/aN99993jlltuif/7v/+L3/3ud7HNNtvEfffdF9tvv32mz9lnnx3Lly+PkSNHxpIlS2LPPfeMRx55JPLy8ip9nQAA2LhkSgAAKoJcCQCQXjlJkiRVPYnqprCwMPLz82Pp0qVOTwSVJGd8TlVPgZRLxvp4g8oiK5WfbQWVT66kMsmUUHnkpPKzraDyyZRUNrkSKk95s1KVXlMcAAAAAAAAACqTojgAAAAAAAAAqaUoDgAAAAAAAEBqKYoDAAAAAAAAkFqK4gAAAAAAAACklqI4AAAAAAAAAKmlKA4AAAAAAABAaimKAwAAAAAAAJBaiuIAAAAAAAAApJaiOAAAAAAAAACppSgOAAAAAAAAQGopigMAAAAAAACQWoriAAAAAAAAAKSWojgAAAAAAAAAqaUoDgAAAAAAAEBqKYoDAAAAAAAAkFqK4gAAAAAAAACklqI4AAAAAAAAAKmlKA4AAAAAAABAaimKAwAAAAAAAJBaiuIAAAAAAAAApJaiOAAAAAAAAACppSgOAAAAAAAAQGopigMAAAAAAACQWoriAAAAAAAAAKSWojgAAAAAAAAAqaUoDgAAAAAAAEBqKYoDAAAAAAAAkFqK4gAAAAAAAACklqI4AAAAAAAAAKmlKA4AAAAAAABAaimKAwAAAAAAAJBaiuIAAAAAAAAApJaiOAAAAAAAAACppSgOAAAAAAAAQGopigMAAAAAAACQWoriAAAAAAAAAKSWojgAAAAAAAAAqVWlRfFnnnkmDjnkkGjVqlXk5OTEfffdt8b+w4cPj5ycnBK3Ll26ZPqMGzeuxOPbbrttJa8JAABVSa4EAGBDyZQAAOlVpUXx5cuXR7du3eKqq64qV//LL788FixYkLl9+OGH0aRJkxg0aFBWvy5dumT1e+655ypj+gAAVBNyJQAAG0qmBABIr82qcuH9+/eP/v37l7t/fn5+5OfnZ+7fd9998eWXX8aIESOy+m222WbRokWLCpsnAADVm1wJAMCGkikBANJrk76m+PXXXx99+/aNNm3aZLW/99570apVq2jfvn0cffTRMX/+/CqaIQAAmwK5EgCADSVTAgBUX1X6S/EN8cknn8S//vWvuOWWW7Lae/XqFVOmTIlOnTrFggULYvz48bHXXnvFG2+8EQ0aNCh1rJUrV8bKlSsz9wsLCyt17gAAVB9yJQAAG0qmBACo3jbZovjUqVOjUaNGMXDgwKz2H57iaIcddohevXpFmzZt4o477ohjjz221LEmTJgQ48ePr8zpAgBQTcmVAABsKJkSAKB62yRPn54kSdxwww1xzDHHRJ06ddbYt1GjRvHTn/405syZU2af0aNHx9KlSzO3Dz/8sKKnDABANSRXAgCwoWRKAIDqb5Msij/99NMxZ86cMr9N+UPLli2L999/P1q2bFlmn9zc3GjYsGHWDQCA9JMrAQDYUDIlAED1V6VF8WXLlsXs2bNj9uzZERExd+7cmD17dsyfPz8ivv9W5NChQ0s87/rrr49evXrF9ttvX+KxM888M55++umYN29evPDCC3HYYYdF7dq146ijjqrUdQEAoOrIlQAAbCiZEgAgvar0muKzZs2KffbZJ3N/1KhRERExbNiwmDJlSixYsCATOostXbo07r777rj88stLHfOjjz6Ko446KhYvXhzNmjWLPffcM1588cVo1qxZ5a0IAABVSq4EAGBDyZQAAOmVkyRJUtWTqG4KCwsjPz8/li5d6vREUElyxudU9RRIuWSsjzeoLLJS+dlWUPnkSiqTTAmVR04qP9sKKp9MSWWTK6HylDcrbZLXFAcAAAAAAACA8lAUBwAAAAAAACC1FMUBAAAAAAAASC1FcQAAAAAAAABSS1EcAAAAAAAAgNRSFAcAAAAAAAAgtRTFAQAAAAAAAEgtRXEAAAAAAAAAUktRHAAAAAAAAIDUUhQHAAAAAAAAILUUxQEAAAAAAABILUVxAAAAAAAAAFJLURwAAAAAAACA1FIUBwAAAAAAACC1FMUBAAAAAAAASC1FcQAAAAAAAABSS1EcAAAAAAAAgNRSFAcAAAAAAAAgtRTFAQAAAAAAAEgtRXEAAAAAAAAAUktRHAAAAAAAAIDUUhQHAAAAAAAAILUUxQEAAAAAAABILUVxAAAAAAAAAFJLURwAAAAAAACA1FIUBwAAAAAAACC1FMUBAAAAAAAASC1FcQAAAAAAAABSS1EcAAAAAAAAgNRSFAcAAAAAAAAgtRTFAQAAAAAAAEgtRXEAAAAAAAAAUktRHAAAAAAAAIDUUhQHAAAAAAAAILUUxQEAAAAAAABILUVxAAAAAAAAAFJLURwAAAAAAACA1FIUBwAAAAAAACC1FMUBAAAAAAAASK0qLYo/88wzccghh0SrVq0iJycn7rvvvjX2nz59euTk5JS4LVy4MKvfVVddFW3bto28vLzo1atXzJw5sxLXAgCAqiZXAgCwoWRKAID0qtKi+PLly6Nbt25x1VVXrdPz3n333ViwYEHm1rx588xjt99+e4waNSrGjh0br776anTr1i369esXn376aUVPHwCAakKuBABgQ8mUAADptVlVLrx///7Rv3//dX5e8+bNo1GjRqU+dumll8bxxx8fI0aMiIiIa665Jh566KG44YYb4txzz92Q6QIAUE3JlQAAbCiZEgAgvTbJa4p37949WrZsGfvvv388//zzmfZVq1bFK6+8En379s201apVK/r27RszZswoc7yVK1dGYWFh1g0AgPSTKwEA2FAyJQBA9bdJFcVbtmwZ11xzTdx9991x9913R+vWraNPnz7x6quv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ACDdZEoAACqCXAkAwNqsV1E8Pz8/636tWrWiU6dOcf7558cBBxxQIRMDACDdZEoAACqCXAkAwNqsV1F88uTJFT0PAABqGJkSAICKIFcCALA261UUL/bKK6/E22+/HRERXbp0iR133LFCJgUAQM0hUwIAUBHkSgAAylJrfZ706aefxr777hu77LJLnHLKKXHKKadEjx49Yr/99ovPPvus3OM888wzccghh0SrVq0iJycn7rvvvrU+Z/r06bHTTjtFbm5udOzYMaZMmVKiz1VXXRVt27aNvLy86NWrV8ycOXMd1g4AgI2hojJlhFwJAFCTOVYJAMDarFdR/OSTT46vvvoq3nzzzfjiiy/iiy++iDfeeCMKCwvjlFNOKfc4y5cvj27dusVVV11Vrv5z586NAQMGxD777BOzZ8+O0047LY477rh49NFHM31uv/32GDVqVIwdOzZeffXV6NatW/Tr1y8+/fTTdV5PAAAqT0Vlygi5EgCgJnOsEgCAtclJkiRZ1yfl5+fHE088EbvssktW+8yZM+OAAw6IJUuWrPtEcnLi3nvvjYEDB5bZ55xzzomHHnoo3njjjUzbkCFDYsmSJfHII49ERESvXr1il112ib/85S8REVFUVBStW7eOk08+Oc4999xyzaWwsDDy8/Nj6dKl0bBhw3VeF2DtcsbnVPUUSLlk7Dp/vAHlVFFZqTIyZYRcCTWNXEllkimh8lRkTnKsEthQMiWVTa6EylPerLRevxQvKiqKzTffvET75ptvHkVFReszZLnMmDEj+vbtm9XWr1+/mDFjRkRErFq1Kl555ZWsPrVq1Yq+fftm+pRm5cqVUVhYmHUDAKByVVWmjJArAQDSxLFKAADWZr2K4vvuu2+ceuqp8cknn2TaPv744zj99NNjv/32q7DJ/djChQujoKAgq62goCAKCwvj66+/js8//zxWr15dap+FCxeWOe6ECRMiPz8/c2vdunWlzB8AIifHza3ybpuYqsqUEXIlAECaOFYJAMDarFdR/C9/+UsUFhZG27Zto0OHDtGhQ4do165dFBYWxpVXXlnRc6x0o0ePjqVLl2ZuH374YVVPCQAg9dKWKSPkSgCAqpC2XClTAgBUvM3W50mtW7eOV199NZ544ol45513IiKic+fOJU4XVNFatGgRixYtympbtGhRNGzYMOrWrRu1a9eO2rVrl9qn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WsSECRPW2O/uu++OLl26RG5ubrRt2zYuueSStY6dk5MTLVq0yLrVrVs3IiLeeOON6N+/f9SvXz8KCgrimGOOic8//zzz3KKiopgwYUK0a9cu6tatG926dYu77rora/yHH344fvrTn0bdunVjn332iXnz5pU6j/vuuy+22WabyMvLi379+sWHH36Yeez999+PQw89NAoKCqJ+/fqxyy67xBNPPJH1/JUrV8Y555wTrVu3jtzc3OjYsWNcf/31pS5rxYoV0b9//9hjjz2camMT8sN9ND8/v8S+W79+/UzfV155JXbeeefYYostYvfdd493330389jw4cNj4MCBWWOfdtpp0adPn8z9Pn36xMknnxynnXZaNG7cOAoKCuK6666L5cuXx4gRI6JBgwbRsWPH+Ne//lVins8//3zssMMOkZeXF7vuumu88cYbmcc++OCDOOSQQ6Jx48ZRr1696NKlSzz88MMbvG369OkTJ510Upx00kmRn58fTZs2jfPOOy+SJNngsakcNXV/3mKLLaJFixax9dZbx6677hoTJ06Mv/3tb3Hddddlva//5z//iX333Tfq1q0bW265ZYwcOTKWLVsWEd9/NtWqVSs+++yziIj44osvolatWjFkyJDM8y+88MLYc889I+L/n1pp2rRpZW5HqEnkSrmSmvs5XB5y5aanpu7PciVULZlSpqTmfgaXh0y5aaqp+7RcWX0oihMREbVr144//vGPceWVV8ZHH31Uap9XXnkljjzyyBgyZEj85z//iXHjxsV5550XU6ZMWa9lLlmyJPbdd9/YcccdY9asWfHII4/EokWL4sgjj8z0mTBhQtx4441xzTXXxJtvvhmnn356/PKXv4ynn346IiI+/PDDOPzww+OQQw6J2bNnx3HHHRfnnntuiWWtWLEi/vCHP8SNN94Yzz//fCxZsiTrzWLZsmVx0EEHxbRp0+Lf//53HHjggXHIIYfE/PnzM32GDh0at956a1xxxRXx9ttvx9/+9resN+kfrtf+++8fRUVF8fjjj1f6NYKoGr///e/jkksuiVmzZsVmm20Wv/rVr9Z5jKlTp0bTpk1j5syZcfLJJ8cJJ5wQgwYNit133z1effXVOOCAA+KYY46JFStWZD3vrLPOiksuuSRefvnlaNasWRxyyCHx7bffRkTEiSeeGCtXroxnnnkm/vOf/8TEiRNL3U/Xx9SpU2OzzTaLmTNnxuWXXx6XXnqp04ulRNr352HDhkXjxo0zpyVavnx59OvXLxo3bhwvv/xy3HnnnfHEE0/ESSedFBERXbp0iS233DLzWfPss89m3Y+IePrpp7OCdkTFbEdIA7lSrmTdpP1zuKz5ypXplPb9Wa6EjUemlClZN2n/DC5rvjJleqV9n5Yrq0hCjTds2LDk0EMPTZIkSXbdddfkV7/6VZIkSXLvvfcmP9xFfvGLXyT7779/1nPPOuusZLvttitz7MmTJycRkdSrVy9zKygoSJIkSS644ILkgAMOyOr/4YcfJhGRvPvuu8k333yTbLHFFskLL7yQ1efYY49NjjrqqCRJkmT06NElln/OOeckEZF8+eWXWXN48cUXM33efvvtJCKSl156qcy5d+nSJbnyyiuTJEmSd999N4mI5PHHHy+171NPPZVERPL2228nO+ywQ3LEEUckK1euLHNsqr/Jkycn+fn5JdqLX+snnngi0/bQQw8lEZF8/fXXSZJk/00VO/XUU5PevXtn7vfu3TvZc889M/e/++67pF69eskxxxyTaVuwYEESEcmMGTOyln3bbbdl+ixevDipW7ducvvttydJkiRdu3ZNxo0bV+71bNOmTXLZZZeVaB87dmzSrVu3rPl27tw5KSoqyrSdc845SefOncu9LKpOTdmfe/funZx66qmlPtarV6+kf//+SZIkybXXXps0btw4WbZsWdZ616pVK1m4cGGSJEly+OGHJyeeeGKSJEly2mmnJWeddVbSuHHj5O23305WrVqVbLHFFsljjz2WtS5r2o5QU8iVpZMra7aa8jksV9YMNWV/liuhasmUpZMpa7aa8hksU9YcNWWfliurF78UJ8vEiRNj6tSp8fbbb5d47O2334499tgjq22PPfaI9957L1avXl3mmA0aNIjZs2dnbi+88EJERLz22mvx1FNPRf369TO3bbfdNiK+P0XQnDlzYsWKFbH//vtn9bnxxhvj/fffz8ypV69eWcvbbbfdSsxhs802i1122SVzf9ttt41GjRpl1nPZsmVx5plnRufOnaNRo0ZRv379ePvttzPfvpw9e3bUrl07evfuvcbtt//++0fHjh3j9ttvjzp16qyxL5u2HXbYIfPvli1bRkTEp59+ut5j1K5dO7bccsvo2rVrpq2goKDUcX+4jzdp0iQ6deqU2ZdPOeWUuPDCC2OPPfaIsWPHxuuvv75Oc1qTXXfdNXJycrLmsba/fzYNNWF/TpIks/++/fbb0a1bt6hXr17m8T322COKiooypxDq3bt3TJ8+PSK+/5blvvvuG3vvvXdMnz49Xn755fj2229LfCZWxHaENJEr5UrKpyZ8Dv+YXJleNWF/lith45IpZUrKpyZ8Bv+YTJluNWGflis3PkVxsuy9997Rr1+/GD16dIWNWatWrejYsWPm1r59+4j4PtwVn0roh7f33nsv9t5778y1Eh566KGsx996660S1+rZUGeeeWbce++98cc//jGeffbZmD17dnTt2jVWrVoVEZG5rtDaDBgwIJ555pl46623KnR+VD+bb7555t/FH1xFRUUR8f0+n/zo+jXFp1cpa4zicdY0bnkcd9xx8b///S+OOeaY+M9//hM777xzXHnllWX2b9iwYSxdurRE+5IlSyI/P7/cy2XTlpb9uSyrV6+O9957L9q1a1fu5/Tp0yfeeuuteO+99+Ktt96KPffcM/r06RPTp0+Pp59+OnMtnh/a0PWFtJEr5UrKJy2fw3IlEenZn8siV8LGJ1PKlJRPWj6DZUqKpWWfLotcWTUUxSnhoosuigceeCBmzJiR1d65c+d4/vnns9qef/75+OlPfxq1a9de5+XstNNO8eabb0bbtm2zgmjHjh2jXr16sd1220Vubm7Mnz+/xOOtW7fOzGnmzJlZ47744osllvXdd9/FrFmzMvfffffdWLJkSXTu3DmzHsOHD4/DDjssunbtGi1atIh58+Zl+nft2jWKioqyrs9QmosuuiiGDRsW++23n7BZgzVr1iwWLFiQ1TZ79uwKG/+H+/iXX34Z//3vfzP7ckRE69at4ze/+U3cc889ccYZZ8R1111X5lidOnWKV155pUT7q6++Gj/96U+z2l566aUS89hmm23W6++fTcemtD+XZerUqfHll1/GEUccERHff3a89tprsXz58kyf559/PmrVqhWdOnWKiO/f9xs3bhwXXnhhdO/ePerXrx99+vSJp59+OqZPn17i+jxA6eRKuZINsyl9DsuVrM2mtD+XRa6EqiFTypRsmE3pM1impDw2pX26LHJl1VAUp4SuXbvG0UcfHVdccUVW+xlnnBHTpk2LCy64IP773//G1KlT4y9/+UuceeaZ67WcE088Mb744os46qij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K7dcXbZsWdWpU6fAx5PT+93JyUkPPfSQVq9erUuXLkmSPvzwQ7m5uWnAgAEFPgYgJ9xTHNC1L8vq1atr7969+V5Gbr+Qy8zMtOq3cuVKbdu2TV988YU2bNigRx55RK+//rq2bdumChUq5LqOrKwsSdJjjz2W45nKkqy+wG/3Xtr9+/fXM888o88++0yjRo3K07z16tVTmTJl9Ouvv9rU//vvv9f999+vTp06ad68eapWrZrKli2rxYsXa+nSpVb9C/I+4XmR03oPHz6s7t27q2HDhpo5c6b8/f3l4uKitWvX6o033jC/dtly+/WqYRjm/+/UqZMOHz6szz77TBs3btS7776rN954Q/Pnz9fw4cMlXbsv5ZYtW/T444+refPmqlChgrKysnTvvfdardOebNnegpaVlSWTyaR169bluP4bP2v2GGNeTJgwQYsXL9akSZPUvn17eXp6ymQyafDgwUX2Whf3fQQAxR2ZU3r88cc1YMAAubi46MiRI5Kk5ORkSdLx48eVkZGh6tWr27Ss3Li6uqpfv35asmSJ/vzzz5ue3ZOVlaUePXroiSeeyPH5O++80+Lx7ebPW32XFkamLCw57Qtb84qt7+Oicjvbku1Wr4Utn8m8/j1kL7aciefj46M9e/Zow4YNWrdundatW6fFixcrLCxMS5YsKYJRAgBuRBbNXfb9lM+fP39by7mZnMaY1+9+W7LfwIED1bFjR3366afauHGjXn31Vb388sv65JNP1KtXL2VmZqpHjx46f/68nnzySTVs2FDu7u46efKkIiIiSvzxxPy+z/N79ruUe4YtyqxekOsqiKye22cyLCxMr776qlavXq0hQ4Zo6dKluu+++wrlbHUgJxTFgf/vvvvu04IFC7R161a1b98+z/Nn//oqOTnZfIkgyfoXbtnatWundu3a6YUXXtDSpUv10EMPadmyZRo+fHiuXzzZv9oqW7as+eyVwpZ92aD8nNlRvnx5devWTZs2bdLx48fNATM3q1atkpubmzZs2CBXV1dz++LFi21eZ61atXK83PiBAwdsH3g+fPHFF0pPT9fnn39u8cu8Gy/RnVdeXl6KjIxUZGSkLl68qE6dOmn69OkaPny4/v77b8XHxysmJkbTpk0zz3Pj9nt7e8vDw+OWYTAv4a9WrVr65ZdflJWVZXGW8f79+83PFwZvb2+VK1fOpte4bt26MgxDtWvXtjqgnV+3E5Bzk/25vtXrs3LlSoWHh1ucWXflyhVzISE/Y7TX6wgApVlpz5zHjx/X0qVLczzI17JlSwUGBmrPnj23vZ6hQ4dq0aJFcnJy0uDBg3PtV7duXV28eDHf22nr97itCiNTFkZ+yY2tecXW93F2Fjl48KDFGSxnzpwp9CvV2LoteXWzz6Stfw/VrVtXWVlZ+v3339W8efNc12Xra5+9nw8cOKBu3bpZPHfgwIF8Z0IXFxf17dtXffv2VVZWlsaOHat33nlHU6dOzfXqDQCAwlXas2huss+KvvFKKIWtII6F5qRatWoaO3asxo4dq9OnT6tly5Z64YUX1KtXL/3666/6448/tGTJEoWFhZnnufGWJ7bm3Lweh8rpGG1BH4fKy/u8Vq1aysrK0sGDB81nrEtSUlKSkpOTLcZUuXJlqyyYkZGhU6dO5XusRZXVr8/V1+e9q1evKiEhQYGBgea26z/n1yuIy743bdpULVq00IcffqiaNWvq2LFjmjNnzm0vF7AVl08H/r8nnnhC7u7uGj58uJKSkqyeP3z4sGbPnp3r/Nn3c7n+voNpaWlWv4L/+++/rX6hlX0gI/sSQuXLl5dk/cXj4+OjLl266J133snxy/bMmTO5ju9Wzp49m+Mvx959911JsrgX9dWrV7V//36bvvCjo6NlGIYefvhhXbx40er5Xbt2mfeRs7OzTCaTxa/Ojhw5otWrV9u8Hb1799a2bdu0Y8cOc9uZM2es7oFY0LJ/jXf9PkxJSbmtEHvu3DmLxxUqVFC9evXM75Oc1ilJs2bNsnjs5OSk0NBQffHFF9q5c6fVerLnd3d3l2T9vstJ7969lZiYqOXLl5vb/vnnH82ZM0cVKlQwX3KpoDk7OyskJESrV6/WsWPHzO379u3Thg0bLPr269dPzs7OiomJsdpHhmFY7V9b5GUf2crb21udOnXSokWLLLZJsnxtnZ2drbZjzpw5Vr/SLAmvIwCUZqU9c3766adW06BBgyRJ77//vt544w1z30uXLmn//v06e/ZsntfTtWtXPffcc3rrrbfk5+eXa7+BAwdq69atVjlCurZf/vnnn5uux9bvcVsVRqYsjPySG1vziq3v4+DgYJUtW1Zz5syxWO6Nebcw2LottrLlM2nr30OhoaFycnLSjBkzrM7mun4d7u7uNr3urVu3lo+Pj+bPn29xWdt169Zp37596tOnjy2baOHGrO3k5KRmzZpJkk2XzgUAFI7SnkVzmvfChQuaNWuWqlatqlatWpnbbyeL2qogjoVeLzMz0+rEJh8fH1WvXv2mxxMNw7B63W3NuXk9DrVjxw5t3brV3JaWlqYFCxYoICCgwG4Nk5f3ee/evSVZ58uZM2dKkkUOqlu3rsV7X5IWLFhwW1c7sjWv3a7WrVvL29tb8+fPV0ZGhrk9Li7Oav05fc4zMzO1YMGCAhnLww8/rI0bN2rWrFmqUqWKevXqVSDLBWzBmeLA/1e3bl0tXbpUgwYNUqNGjRQWFqamTZsqIyNDW7Zs0YoVKxQREZHr/D179tQdd9yhYcOG6fHHH5ezs7MWLVokb29vi+CwZMkSzZs3Tw8++KDq1q2rCxcuaOHChfLw8DB/CZcrV06NGzfW8uXLdeedd8rLy0tNmzZV06ZNNXfuXN1zzz266667NGLECNWpU0dJSUnaunWrTpw4oZ9//jlf2//f//5X8+fPV2hoqOrUqaMLFy5ow4YN+uqrr9S3b1+LX5CdPHlSjRo1Unh4uOLi4m663A4dOmju3LkaO3asGjZsqIcfflj169fXhQsXtHnzZn3++ed6/vnnJV0LGTNnztS9996roUOH6vTp05o7d67q1atndS/t3DzxxBP64IMPdO+992rixIlyd3fXggULzGfEFpaePXuaz4QYNWqULl68qIULF8rHxyffvxZs3LixunTpolatWsnLy0s7d+7UypUrNX78eEnXLgfUqVMnvfLKK7p69apq1KihjRs3KiEhwWpZL774ojZu3KjOnTtr5MiRatSokU6dOqUVK1bohx9+UKVKldS8eXM5Ozvr5ZdfVkpKilxdXdWtWzf5+PhYLW/kyJF65513FBERoV27dikgIEArV67Ujz/+qFmzZqlixYr52mZbxMTEaP369erYsaPGjh1rLuI2adLE4jWuW7eunn/+eU2ZMkVHjhxRaGioKlasqISEBH366acaOXKkHnvssTytu27duqpUqZLmz5+vihUryt3dXUFBQbd17ypJevPNN3XPPfeoZcuWGjlypGrXrq0jR45ozZo15rPl7rvvPn3wwQfy9PRU48aNtXXrVn399deqUqWKxbJKyusIAKVVac+coaGhVm3Z33W9evVS1apVze07duxQ165dFR0dfdNLoOfEyclJzz777C37Pf744/r888913333KSIiQq1atVJaWpp+/fVXrVy5UkeOHLEYU05s+R63VWFkyrxkg9tla16x9X3s7e2txx57TLGxsbrvvvvUu3dv/e9//9O6detu+boU1bbYypbPpK1/D9WrV0/PPPOMnnvuOXXs2FH9+vWTq6urfvrpJ1WvXl2xsbGSpFatWuntt9/W888/r3r16snHx8fqTHDp2pl4L7/8siIjI9W5c2cNGTJESUlJmj17tgICAjR58uQ8b+/w4cN1/vx5devWTTVr1tTRo0c1Z84cNW/e3OIsLABA0SrtWXTu3LlavXq1+vbtqzvuuEOnTp0yF30/+OADubi4mPveTha1VUEcC73ehQsXVLNmTfXv31+BgYGqUKGCvv76a/3000/mq980bNhQdevW1WOPPaaTJ0/Kw8NDq1atyvEqPLbk3OwfEjzzzDMaPHiwypYtq759+5qL5dd76qmn9NFHH6lXr1569NFH5eXlpSVLlighIUGrVq2yuIrh7cjL+zwwMFDh4eFasGCBkpOT1blzZ+3YsUNLlixRaGiounbtal7u8OHDNXr0aP3rX/9Sjx499PPPP2vDhg23lUttzWu3q2zZsnr++ec1atQodevWTYMGDVJCQoIWL15sdU/xJk2aqF27dpoyZYrOnz8vLy8vLVu27JY/GLbV0KFD9cQTT+jTTz/VmDFjVLZs2QJZLmATA4CFP/74wxgxYoQREBBguLi4GBUrVjTuvvtuY86cOcaVK1fM/WrVqmWEh4dbzLtr1y4jKCjIcHFxMe644w5j5syZxuLFiw1JRkJCgmEYhrF7925jyJAhxh133GG4uroaPj4+xn333Wfs3LnTYllbtmwxWrVqZbi4uBiSjOjoaPNzhw8fNsLCwgw/Pz+jbNmyRo0aNYz77rvPWLlypblP9np/+uknm7b7p59+MgYMGGAel7u7u9GyZUtj5syZxtWrVy36JiQkGJKstv9mdu3aZQwdOtSoXr26UbZsWaNy5cpG9+7djSVLlhiZmZnmfu+9955Rv359w9XV1WjYsKGxePFiIzo62rjxnytJxrhx43Jc1y+//GJ07tzZcHNzM2rUqGE899xzxnvvvWfxOtiiT58+Rq1atSzaatWqZfTp0yfH/p9//rnRrFkzw83NzQgICDBefvllY9GiRVbrzW0ZnTt3Njp37mx+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p6dSUlLk4eFRMBsHAADgIBwhK5lMJn366acKDQ3Ntc+TTz6pNWvWWPz4cvDgwUpOTtb69ettWo8j7CsAAIDC4Ag5iUwJAABgf7ZmpWJ1T/GUlBRJkpeXV659tm7dquDgYIu2kJAQbd26VdK1X18mJiZa9PH09FRQUJC5z43S09OVmppqMQEAAKB0u1XuzAm5EgAAANcjUwIAABQPZew9gGxZWVmaNGmS7r77bjVt2jTXfomJifL19bVo8/X1VWJiovn57Lbc+twoNjZWMTExtzN8AABsYzLZewRwZMXnAkAOIbfcmZqaqsuXL6tcuXJW85ArgaJniuG7FYXHiOa7FcDtIVMCJQOZEoWNXAnYX7E5U3zcuHHau3evli1bVuTrnjJlilJSUszT8ePHi3wMAAAAKPnIlQAAALhdZEoAAICCVyzOFB8/fry+/PJLfffdd6pZs+ZN+/r5+SkpKcmiLSkpSX5+fubns9uqVatm0ad58+Y5LtPV1VWurq63sQUAAABwNLnlTg8PjxzP6JHIlQAAALBEpgQAACge7HqmuGEYGj9+vD799FNt2rRJtWvXvuU87du3V3x8vEXbV199pfbt20uSateuLT8/P4s+qamp2r59u7kPAAAAcCu3yp0AAADArZApAQAAige7FsXHjRun//73v1q6dKkqVqyoxMREJSYm6vLly+Y+YWFhmjJlivnxxIkTtX79er3++uvav3+/pk+frp07d2r8+PGSJJPJpEmTJun555/X559/rl9//VVhYWGqXr26QkNDi3oTAQAAUExcvHhRe/bs0Z49eyRJCQkJ2rNnj44dOybp2mUqw8LCzP1Hjx6tP//8U0888YT279+vefPm6eOPP9bkyZPtMXwAAAAUA2RKAACAksmul09/++23JUldunSxaF+8eLEiIiIkSceOHZOT0//V7jt06KClS5fq2Wef1dNPP6369etr9erVatq0qbnPE088obS0NI0cOVLJycm65557tH79erm5uRX6NgEAAKB42rlzp7p27Wp+HBUVJUkKDw9XXFycTp06ZT6YKV27AtGaNWs0efJkzZ49WzVr1tS7776rkJCQIh87AAAAigcyJQAAQMlkMgzDsPcgipvU1FR5enoqJSVFHh4e9h4OAMCRmEz2HgEcWRHFOrKS7dhXQOEzxfDdisJjRHPIBCgs5CTbsa+Awkem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hZE7AQAA4H7IlQAAAK7HwxhjnD0IIL+uXbumWbNmacKECQ6PkQKsinkPd8XcB1CY+I6BO2Lewx0x7wEUJr5j4K6Y+3BHzHvXR1EcAAAAAAAAAAAAAGBZnnduAgAAAAAAAAAAAACAa6IoDgAAAAAAAAAAAACwLIrisJzExER5eHgoIyNDkrR06VIFBgY+0GPCupz5d808Q0FjPgPA7ZErUZi4D8NKmM8AkDcyJQoT92BYDXMahYmiOBQVFSUPDw/FxcXZrV+zZo08PDzuq++lS5fKw8PDYXnvvffuq1+gMOQ2V29dJk+e7OwhFrhKlSpp7ty5DusnT56sevXqPfDxoOC443yOiIiwnZ+3t7ceeeQRdezYUatXr3b20AC3Qa4EbnDH+zC50rrccT6TKwHnIlMCN7jjPZhMaW3uOKfJlUULRXFIknx8fDR79mxdvHixwPsOCAjQmTNn7JbevXsX+HGA+3XrHJ07d67D3B0zZoyzhwjkm7vO55deeklnzpzRsWPHtGrVKj3xxBPq0aOHBg8e7OyhAW6DXAm4730Y1uSu85lcCTgXmRJw33swrMtd5zS5suigKA5JUtu2bRUSEqJZs2bdtt2qVatUq1YteXt7q1KlSpozZ84d+/bw8FBISIjd4uvrK0k6cOCAOnToIH9/fwUHB6tPnz766aefbPvm5ORo1qxZqly5snx9fVW3bl3961//sut/3bp1qlGjhnx9ffX000/rxIkTuY5jzZo1ql69unx8fBQZGalTp07Zth07dkydOnVScHCw/P391ahRI3311Vd2+1+7dk3jx49XxYoV5e3trWrVqumf//xnrse6cuWKOnTooPDwcB614UJunaOlSpVymLv+/v62trt371bDhg1VokQJNW/eXGlpabZtUVFR6ty5s13fMTExioiIsH2OiIjQiBEjFBMTo6CgIAUHB2vx4sXKyspS//79VbJkSVWrVk3r1693GGdSUpLq1KkjHx8fNW3aVAcOHLBt++GHH9SxY0cFBQXJz89PtWrV0rp16+772kRERGj48OEaPny4SpUqpbJly2rixIkyxtx33ygc7jqfS5QooZCQED366KNq2rSpZs+erUWLFmnx4sV23+v79+9X69at5evrqzJlymjw4MHKzMyUdOPe5OnpqXPnzkmSLly4IE9PT/Xo0cO2//Tp09WiRQtJ//9opYSE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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ - "from sklearn.feature_extraction.text import CountVectorizer\n", - "from sklearn.decomposition import LatentDirichletAllocation\n", - "\n", - "# Extract negative feedback messages\n", - "feedback_messages = [item['question'] for item in conversation_data]\n", - "\n", - "# Custom tokenizer to handle specific patterns\n", - "def custom_tokenizer(text):\n", - " # Split by non-alphanumeric characters\n", - " tokens = text.split()\n", - " # Remove numbers and tokens less than 3 characters long\n", - " tokens = [token for token in tokens if not token.isdigit() and len(token) > 2]\n", - " return tokens\n", - "\n", - "# Vectorize the feedback messages with custom tokenizer\n", - "vectorizer = CountVectorizer(stop_words='english', tokenizer=custom_tokenizer)\n", - "X = vectorizer.fit_transform(feedback_messages)\n", - "\n", - "# Fit LDA model\n", - "lda = LatentDirichletAllocation(n_components=2, random_state=42)\n", - "lda.fit(X)\n", - "\n", - "# Display topics\n", - "def display_topics(model, feature_names, num_top_words):\n", - " for topic_idx, topic in enumerate(model.components_):\n", - " print(f\"Topic {topic_idx}:\")\n", - " print(\" \".join([feature_names[i] for i in topic.argsort()[:-num_top_words - 1:-1]]))\n", - "\n", - "num_top_words = 5\n", - "feature_names = vectorizer.get_feature_names_out()\n", - "display_topics(lda, feature_names, num_top_words)\n" + "from collections import defaultdict\n", + "\n", + "# Group questions by cluster\n", + "clustered_questions = defaultdict(list)\n", + "for i, cluster in enumerate(clusters):\n", + " clustered_questions[cluster].append({'question': questions[i], 'feedback': feedbacks[i]})\n", + "\n", + "# Create a conversation_data variable with clustered questions and feedback\n", + "conversation_data = []\n", + "for cluster, items in clustered_questions.items():\n", + " for item in items:\n", + " conversation_data.append({\"question\": item['question'], \"feedback\": item['feedback']})\n", + "\n", + "# Plot feedback distribution in each cluster\n", + "fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(20, 10)) # Adjust the nrow and ncols based on the number of clusters\n", + "axes = axes.flatten()\n", + "\n", + "for cluster, items in clustered_questions.items():\n", + " feedback_counts = defaultdict(int)\n", + " for item in items:\n", + " feedback_counts[item['feedback']] += 1\n", + " \n", + " feedback_types = ['No Feedback', 'Thumbs Up', 'Thumbs Down']\n", + " counts = [feedback_counts[0], feedback_counts[1], feedback_counts[2]]\n", + " \n", + " axes[cluster].bar(feedback_types, counts, color=['gray', 'green', 'red'])\n", + " axes[cluster].set_title(f'Cluster {cluster}: {main_themes.get(cluster, \"Unknown\")}')\n", + " axes[cluster].set_xlabel('Feedback Type')\n", + " axes[cluster].set_ylabel('Count')\n", + "\n", + "plt.tight_layout()\n", + "plt.show()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Questions in Cluster 3 grouped by feedback type:\n", + "Total number of questions: 2\n", + "\n", + "Feedback Type: Thumbs Down (Total: 2)\n", + " - what is the card used in this transaction?\n", + " - What is the ID of the card used in transaction 565964?\n" + ] + } + ], "source": [ - "from sklearn.feature_extraction.text import TfidfVectorizer\n", - "from sklearn.cluster import KMeans\n", - "\n", - "# Extract feedback messages\n", - "feedback_messages = [item['question'] for item in conversation_data]\n", - "\n", - "# Vectorize the feedback messages\n", - "vectorizer = TfidfVectorizer(stop_words='english')\n", - "X = vectorizer.fit_transform(feedback_messages)\n", - "\n", - "# Apply K-means clustering\n", - "num_clusters = 4 # Number of clusters\n", - "kmeans = KMeans(n_clusters=num_clusters, random_state=42)\n", - "kmeans.fit(X)\n", - "\n", - "# Print clustering results\n", - "print(\"Clustering results:\")\n", - "for i in range(num_clusters):\n", - " cluster_label = f\"Cluster {i}:\"\n", - " cluster_messages = [feedback_messages[j] for j in range(len(kmeans.labels_)) if kmeans.labels_[j] == i]\n", - " print(cluster_label)\n", - " for message in cluster_messages:\n", - " print(f\"- {message}\")\n", - "\n", - "# Print cluster centroids (important words for each cluster)\n", - "print(\"\\nCluster centroids (top words per cluster):\")\n", - "order_centroids = kmeans.cluster_centers_.argsort()[:, ::-1]\n", - "terms = vectorizer.get_feature_names_out()\n", - "for i in range(num_clusters):\n", - " print(f\"Cluster {i} words:\", end='')\n", - " for ind in order_centroids[i, :10]: # Print top 10 words per cluster\n", - " print(f' {terms[ind]}', end='')\n", - " print()\n", - "\n" + "# After plotting feedback distribution, group and print all questions by feedback type in cluster 1\n", + "cluster_to_view = 3 # Change this to the cluster number you want to view\n", + "\n", + "# Initialize a dictionary to store questions grouped by feedback type\n", + "grouped_by_feedback = defaultdict(list)\n", + "\n", + "# Group questions by feedback type\n", + "for item in clustered_questions[cluster_to_view]:\n", + " question = item['question']\n", + " feedback = item['feedback']\n", + " feedback_str = \"No Feedback\" if feedback == 0 else \"Thumbs Up\" if feedback == 1 else \"Thumbs Down\"\n", + " grouped_by_feedback[feedback_str].append(question)\n", + "\n", + "# Print questions grouped by feedback type\n", + "print(f\"Questions in Cluster {cluster_to_view} grouped by feedback type:\")\n", + "\n", + "# Total number of questions in the cluster\n", + "total_questions = sum(len(questions) for questions in grouped_by_feedback.values())\n", + "print(f\"Total number of questions: {total_questions}\")\n", + "\n", + "for feedback_type, questions in grouped_by_feedback.items():\n", + " print(f\"\\nFeedback Type: {feedback_type} (Total: {len(questions)})\")\n", + " for question in questions:\n", + " print(f\" - {question}\")" ] } ], diff --git a/copilot/docs/notebooks/TransactionFraud_demo.ipynb b/copilot/docs/notebooks/TransactionFraud_demo.ipynb index 39153aed..a05db1aa 100644 --- a/copilot/docs/notebooks/TransactionFraud_demo.ipynb +++ b/copilot/docs/notebooks/TransactionFraud_demo.ipynb @@ -16,15 +16,15 @@ "from pyTigerGraph import TigerGraphConnection\n", "\n", "conn = TigerGraphConnection(\n", - " host=\"https://tg-26bfd0cd-6582-414e-937e-e2c83ecb5a79.us-east-1.i.tgcloud.io\", \n", + " host=\"https://YOUR_DB_ADDRESS\", \n", " graphname=\"Transaction_Fraud\", \n", - " username=\"supportai\", \n", - " password=\"supportai\"\n", + " username=\"YOUR_DB_USERNAME\", \n", + " password=\"YOUR_DB_PASSWORD\"\n", ")\n", "\n", "conn.getToken()\n", "\n", - "conn.ai.configureCoPilotHost(hostname=\"http://0.0.0.0:8000\")" + "conn.ai.configureCoPilotHost(hostname=\"http://COPILOT_ADDRESS\")" ] }, { @@ -34,18 +34,18 @@ "List of questions:\n", "1. Find all transactions, from 2/1/21 to 5/1/21, above average amount for that card. Sort the results.\n", "\n", - "2. Provide more details about the transaction 871054, like the card used and merchant involved in this transaction.\n", + "2. Provide more details about the transaction 871054.\n", "\n", - "3. What is the average transaction amount for the card used in this transaction over the past 6 months?\n", + "3. What is the average transaction amount for the card 4039101933538921 used in this transaction over the past 6 months?\n", "\n", - "4. What do we know about the merchant involved in the transaction 871054?\n", + "4. What do we know about the merchant fraud_Kuhn LLC involved in the transaction 871054?\n", "\n", "5. Are there any activities of the user associated with the transaction 871054 that might be interesting to look into for further investigation? " ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -53,31 +53,45 @@ "output_type": "stream", "text": [ "Run 1:\n", - "I'm sorry, I don't know the answer to that question. Please try rephrasing your question.\n" - ] - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[3], line 27\u001b[0m\n\u001b[1;32m 22\u001b[0m start_time \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime()\n\u001b[1;32m 23\u001b[0m payload \u001b[38;5;241m=\u001b[39m {\n\u001b[1;32m 24\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mquery\u001b[39m\u001b[38;5;124m\"\u001b[39m: question\n\u001b[1;32m 25\u001b[0m }\n\u001b[0;32m---> 27\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43mrequests\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpost\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mhttp://0.0.0.0:8000/Transaction_Fraud/query_with_history\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\n\u001b[1;32m 28\u001b[0m \u001b[43m \u001b[49m\u001b[43mjson\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mpayload\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\n\u001b[1;32m 29\u001b[0m \u001b[43m \u001b[49m\u001b[43mauth\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mHTTPBasicAuth\u001b[49m\u001b[43m(\u001b[49m\u001b[43mconn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43musername\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mconn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpassword\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 30\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 31\u001b[0m \u001b[38;5;28mprint\u001b[39m (json\u001b[38;5;241m.\u001b[39mloads(res\u001b[38;5;241m.\u001b[39mtext)\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnatural_language_response\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mno answer\u001b[39m\u001b[38;5;124m\"\u001b[39m))\n\u001b[1;32m 32\u001b[0m end_time \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime()\n", - "File \u001b[0;32m~/Documents/github/CoPilot/venv/lib/python3.11/site-packages/requests/api.py:115\u001b[0m, in \u001b[0;36mpost\u001b[0;34m(url, data, json, **kwargs)\u001b[0m\n\u001b[1;32m 103\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mpost\u001b[39m(url, data\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, json\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m 104\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124mr\u001b[39m\u001b[38;5;124;03m\"\"\"Sends a POST request.\u001b[39;00m\n\u001b[1;32m 105\u001b[0m \n\u001b[1;32m 106\u001b[0m \u001b[38;5;124;03m :param url: URL for the new :class:`Request` object.\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 112\u001b[0m \u001b[38;5;124;03m :rtype: requests.Response\u001b[39;00m\n\u001b[1;32m 113\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 115\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mpost\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mjson\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mjson\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/Documents/github/CoPilot/venv/lib/python3.11/site-packages/requests/api.py:59\u001b[0m, in \u001b[0;36mrequest\u001b[0;34m(method, url, **kwargs)\u001b[0m\n\u001b[1;32m 55\u001b[0m \u001b[38;5;66;03m# By using the 'with' statement we are sure the session is closed, thus we\u001b[39;00m\n\u001b[1;32m 56\u001b[0m \u001b[38;5;66;03m# avoid leaving sockets open which can trigger a ResourceWarning in some\u001b[39;00m\n\u001b[1;32m 57\u001b[0m \u001b[38;5;66;03m# cases, and look like a memory leak in others.\u001b[39;00m\n\u001b[1;32m 58\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m sessions\u001b[38;5;241m.\u001b[39mSession() \u001b[38;5;28;01mas\u001b[39;00m session:\n\u001b[0;32m---> 59\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43msession\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmethod\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/Documents/github/CoPilot/venv/lib/python3.11/site-packages/requests/sessions.py:589\u001b[0m, in \u001b[0;36mSession.request\u001b[0;34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001b[0m\n\u001b[1;32m 584\u001b[0m send_kwargs \u001b[38;5;241m=\u001b[39m {\n\u001b[1;32m 585\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtimeout\u001b[39m\u001b[38;5;124m\"\u001b[39m: timeout,\n\u001b[1;32m 586\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mallow_redirects\u001b[39m\u001b[38;5;124m\"\u001b[39m: allow_redirects,\n\u001b[1;32m 587\u001b[0m }\n\u001b[1;32m 588\u001b[0m send_kwargs\u001b[38;5;241m.\u001b[39mupdate(settings)\n\u001b[0;32m--> 589\u001b[0m resp \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprep\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43msend_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 591\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m resp\n", - "File \u001b[0;32m~/Documents/github/CoPilot/venv/lib/python3.11/site-packages/requests/sessions.py:703\u001b[0m, in \u001b[0;36mSession.send\u001b[0;34m(self, request, **kwargs)\u001b[0m\n\u001b[1;32m 700\u001b[0m start \u001b[38;5;241m=\u001b[39m preferred_clock()\n\u001b[1;32m 702\u001b[0m \u001b[38;5;66;03m# Send the request\u001b[39;00m\n\u001b[0;32m--> 703\u001b[0m r \u001b[38;5;241m=\u001b[39m \u001b[43madapter\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 705\u001b[0m \u001b[38;5;66;03m# Total elapsed time of the request (approximately)\u001b[39;00m\n\u001b[1;32m 706\u001b[0m elapsed \u001b[38;5;241m=\u001b[39m preferred_clock() \u001b[38;5;241m-\u001b[39m start\n", - "File \u001b[0;32m~/Documents/github/CoPilot/venv/lib/python3.11/site-packages/requests/adapters.py:486\u001b[0m, in \u001b[0;36mHTTPAdapter.send\u001b[0;34m(self, request, stream, timeout, verify, cert, proxies)\u001b[0m\n\u001b[1;32m 483\u001b[0m timeout \u001b[38;5;241m=\u001b[39m TimeoutSauce(connect\u001b[38;5;241m=\u001b[39mtimeout, read\u001b[38;5;241m=\u001b[39mtimeout)\n\u001b[1;32m 485\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 486\u001b[0m resp \u001b[38;5;241m=\u001b[39m \u001b[43mconn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43murlopen\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 487\u001b[0m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 488\u001b[0m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 489\u001b[0m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 490\u001b[0m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 491\u001b[0m \u001b[43m \u001b[49m\u001b[43mredirect\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 492\u001b[0m \u001b[43m \u001b[49m\u001b[43massert_same_host\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 493\u001b[0m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 494\u001b[0m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 495\u001b[0m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmax_retries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 496\u001b[0m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 497\u001b[0m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 498\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 500\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (ProtocolError, \u001b[38;5;167;01mOSError\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m err:\n\u001b[1;32m 501\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mConnectionError\u001b[39;00m(err, request\u001b[38;5;241m=\u001b[39mrequest)\n", - "File \u001b[0;32m~/Documents/github/CoPilot/venv/lib/python3.11/site-packages/urllib3/connectionpool.py:715\u001b[0m, in \u001b[0;36mHTTPConnectionPool.urlopen\u001b[0;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)\u001b[0m\n\u001b[1;32m 712\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_prepare_proxy(conn)\n\u001b[1;32m 714\u001b[0m \u001b[38;5;66;03m# Make the request on the httplib connection object.\u001b[39;00m\n\u001b[0;32m--> 715\u001b[0m httplib_response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_make_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 716\u001b[0m \u001b[43m \u001b[49m\u001b[43mconn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 717\u001b[0m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 718\u001b[0m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 719\u001b[0m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtimeout_obj\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 720\u001b[0m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 721\u001b[0m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 722\u001b[0m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 723\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 725\u001b[0m \u001b[38;5;66;03m# If we're going to release the connection in ``finally:``, then\u001b[39;00m\n\u001b[1;32m 726\u001b[0m \u001b[38;5;66;03m# the response doesn't need to know about the connection. Otherwise\u001b[39;00m\n\u001b[1;32m 727\u001b[0m \u001b[38;5;66;03m# it will also try to release it and we'll have a double-release\u001b[39;00m\n\u001b[1;32m 728\u001b[0m \u001b[38;5;66;03m# mess.\u001b[39;00m\n\u001b[1;32m 729\u001b[0m response_conn \u001b[38;5;241m=\u001b[39m conn \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m release_conn \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n", - "File \u001b[0;32m~/Documents/github/CoPilot/venv/lib/python3.11/site-packages/urllib3/connectionpool.py:467\u001b[0m, in \u001b[0;36mHTTPConnectionPool._make_request\u001b[0;34m(self, conn, method, url, timeout, chunked, **httplib_request_kw)\u001b[0m\n\u001b[1;32m 462\u001b[0m httplib_response \u001b[38;5;241m=\u001b[39m conn\u001b[38;5;241m.\u001b[39mgetresponse()\n\u001b[1;32m 463\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 464\u001b[0m \u001b[38;5;66;03m# Remove the TypeError from the exception chain in\u001b[39;00m\n\u001b[1;32m 465\u001b[0m \u001b[38;5;66;03m# Python 3 (including for exceptions like SystemExit).\u001b[39;00m\n\u001b[1;32m 466\u001b[0m \u001b[38;5;66;03m# Otherwise it looks like a bug in the code.\u001b[39;00m\n\u001b[0;32m--> 467\u001b[0m \u001b[43msix\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mraise_from\u001b[49m\u001b[43m(\u001b[49m\u001b[43me\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[1;32m 468\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (SocketTimeout, BaseSSLError, SocketError) \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 469\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_raise_timeout(err\u001b[38;5;241m=\u001b[39me, url\u001b[38;5;241m=\u001b[39murl, timeout_value\u001b[38;5;241m=\u001b[39mread_timeout)\n", - "File \u001b[0;32m:3\u001b[0m, in \u001b[0;36mraise_from\u001b[0;34m(value, from_value)\u001b[0m\n", - "File \u001b[0;32m~/Documents/github/CoPilot/venv/lib/python3.11/site-packages/urllib3/connectionpool.py:462\u001b[0m, in \u001b[0;36mHTTPConnectionPool._make_request\u001b[0;34m(self, conn, method, url, timeout, chunked, **httplib_request_kw)\u001b[0m\n\u001b[1;32m 459\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m:\n\u001b[1;32m 460\u001b[0m \u001b[38;5;66;03m# Python 3\u001b[39;00m\n\u001b[1;32m 461\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 462\u001b[0m httplib_response \u001b[38;5;241m=\u001b[39m \u001b[43mconn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgetresponse\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 463\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 464\u001b[0m \u001b[38;5;66;03m# Remove the TypeError from the exception chain in\u001b[39;00m\n\u001b[1;32m 465\u001b[0m \u001b[38;5;66;03m# Python 3 (including for exceptions like SystemExit).\u001b[39;00m\n\u001b[1;32m 466\u001b[0m \u001b[38;5;66;03m# Otherwise it looks like a bug in the code.\u001b[39;00m\n\u001b[1;32m 467\u001b[0m six\u001b[38;5;241m.\u001b[39mraise_from(e, \u001b[38;5;28;01mNone\u001b[39;00m)\n", - "File \u001b[0;32m/opt/homebrew/Cellar/python@3.11/3.11.9/Frameworks/Python.framework/Versions/3.11/lib/python3.11/http/client.py:1395\u001b[0m, in \u001b[0;36mHTTPConnection.getresponse\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1393\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 1394\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m-> 1395\u001b[0m \u001b[43mresponse\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbegin\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1396\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mConnectionError\u001b[39;00m:\n\u001b[1;32m 1397\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mclose()\n", - "File \u001b[0;32m/opt/homebrew/Cellar/python@3.11/3.11.9/Frameworks/Python.framework/Versions/3.11/lib/python3.11/http/client.py:325\u001b[0m, in \u001b[0;36mHTTPResponse.begin\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 323\u001b[0m \u001b[38;5;66;03m# read until we get a non-100 response\u001b[39;00m\n\u001b[1;32m 324\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[0;32m--> 325\u001b[0m version, status, reason \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_read_status\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 326\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m status \u001b[38;5;241m!=\u001b[39m CONTINUE:\n\u001b[1;32m 327\u001b[0m \u001b[38;5;28;01mbreak\u001b[39;00m\n", - "File \u001b[0;32m/opt/homebrew/Cellar/python@3.11/3.11.9/Frameworks/Python.framework/Versions/3.11/lib/python3.11/http/client.py:286\u001b[0m, in \u001b[0;36mHTTPResponse._read_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 285\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_read_status\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m--> 286\u001b[0m line \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mstr\u001b[39m(\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mreadline\u001b[49m\u001b[43m(\u001b[49m\u001b[43m_MAXLINE\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124miso-8859-1\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 287\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(line) \u001b[38;5;241m>\u001b[39m _MAXLINE:\n\u001b[1;32m 288\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m LineTooLong(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mstatus line\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", - "File \u001b[0;32m/opt/homebrew/Cellar/python@3.11/3.11.9/Frameworks/Python.framework/Versions/3.11/lib/python3.11/socket.py:706\u001b[0m, in \u001b[0;36mSocketIO.readinto\u001b[0;34m(self, b)\u001b[0m\n\u001b[1;32m 704\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[1;32m 705\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 706\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_sock\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrecv_into\u001b[49m\u001b[43m(\u001b[49m\u001b[43mb\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 707\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m timeout:\n\u001b[1;32m 708\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_timeout_occurred \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + "The transactions from 2/1/21 to 5/1/21 above average amount for that card are as follows: Transaction with id 39843 on 2021-04-17 17:36:29 with amount 7855.36, Transaction with id 871054 on 2021-02-02 00:00:00 with amount 5321.52, Transaction with id 40831 on 2021-04-24 23:45:10 with amount 2934.13, Transaction with id 34336 on 2021-04-24 12:24:53 with amount 4935.42, Transaction with id 473824 on 2021-04-18 14:29:51 with amount 3713.09, Transaction with id 7815 on 2021-04-17 16:05:56 with amount 6044.24, Transaction with id 769 on 2021-04-17 23:31:10 with amount 2802.55.\n", + "Transaction 871054 is a payment transaction that occurred at 2021-02-02 00:00:00. The amount of the transaction was 5321.52. It is marked as a fraudulent transaction. There are no repeated cards, merchant transactions, or common code transactions associated with this transaction. The transaction does not have any merchant category, occupation, or gender associated with it. The age and city population related to this transaction are also not available.\n", + "The average transaction amount for the card number 4039101933538921 over the past 6 months is 82.47301270417434.\n", + "The merchant involved in the transaction 871054 is named fraud_Kuhn LLC. This merchant falls under the 'home' category. The merchant's Pagerank Score is 1.235146 and it belongs to the community with the ID 13631497. However, the size of this community is 0.\n", + "Yes, there are two activities associated with the transaction 871054 that might be interesting for further investigation. The first activity is a 'Buyer address update', indicating that the buyer has recently moved to another state. The second activity is a 'Card average amount anomaly', suggesting that the transaction amount is significantly larger than the average amount typically spent using the card.\n", + "\n", + "Run 2:\n", + "The transactions from 2/1/21 to 5/1/21 that were above the average amount for that card are as follows: Transaction ID 39843 on 2021-04-17 with an amount of 7855.36, Transaction ID 40831 on 2021-04-24 with an amount of 2934.13, Transaction ID 871054 on 2021-02-02 with an amount of 5321.52, Transaction ID 473824 on 2021-04-18 with an amount of 3713.09, Transaction ID 34336 on 2021-04-24 with an amount of 4935.42, Transaction ID 7815 on 2021-04-17 with an amount of 6044.24, and Transaction ID 769 on 2021-04-17 with an amount of 2802.55.\n", + "Transaction 871054 is a payment transaction that occurred at the time 2021-02-02 00:00:00. The amount involved in this transaction is 5321.52. This transaction has been flagged as fraudulent. There are no repeated cards, common merchant transactions, or common code transactions associated with this transaction. The merchant category, occupation, and gender associated with this transaction are not specified. The age and city population are also not provided.\n", + "The average transaction amount for the card 4039101933538921 over the past 6 months is 82.47301270417434.\n", + "The merchant involved in the transaction 871054 is named fraud_Kuhn LLC. This merchant falls under the 'home' category. It has a Pagerank Score of 1.235146 and is part of the community with the ID 13631497. However, the size of this community is 0.\n", + "Yes, there are two activities associated with the transaction 871054 that might be interesting for further investigation. The first activity is a 'Buyer address update' indicating that the buyer has recently moved to another state. The second activity is a 'Card average amount anomaly' which suggests that the transaction amount is significantly larger than the average amount typically spent using the card.\n", + "\n", + "Run 3:\n", + "The transactions from 2/1/21 to 5/1/21 above the average amount for that card are as follows: Transaction ID 769 on 2021-04-17 with an amount of 2802.55, Transaction ID 473824 on 2021-04-18 with an amount of 3713.09, Transaction ID 871054 on 2021-02-02 with an amount of 5321.52, Transaction ID 39843 on 2021-04-17 with an amount of 7855.36, Transaction ID 7815 on 2021-04-17 with an amount of 6044.24, Transaction ID 40831 on 2021-04-24 with an amount of 2934.13, and Transaction ID 34336 on 2021-04-24 with an amount of 4935.42.\n", + "Transaction 871054 is a payment transaction that occurred at 2021-02-02 00:00:00. The amount involved in the transaction is 5321.52. The transaction is marked as fraudulent. There are no repeated cards, common merchant transactions, common card transactions, or merchant categories involved in this transaction. The transaction does not have any in-degree or out-degree. The age, city population, occupation, and gender related to this transaction are not specified.\n", + "The average transaction amount for the card 4039101933538921 over the past 6 months is 82.47301270417434.\n", + "The merchant involved in the transaction 871054 is named fraud_Kuhn LLC. This merchant falls under the 'home' category. The merchant has a Pagerank Score of 1.235146. The Community ID associated with this merchant is 13631497, however, the community size is 0.\n", + "Yes, there are two activities associated with the transaction 871054 that might be interesting for further investigation. The first activity is a 'Buyer address update' indicating that the buyer has recently moved to another state. The second activity is a 'Card average amount anomaly' which suggests that the transaction amount is significantly larger than the average amount typically spent using the card.\n", + "\n", + "Run 4:\n", + "The transactions from 2/1/21 to 5/1/21 that were above the average amount for that card are as follows: Transaction ID 40831 on 2021-04-24 with an amount of 2934.13, Transaction ID 871054 on 2021-02-02 with an amount of 5321.52, Transaction ID 39843 on 2021-04-17 with an amount of 7855.36, Transaction ID 769 on 2021-04-17 with an amount of 2802.55, Transaction ID 473824 on 2021-04-18 with an amount of 3713.09, Transaction ID 34336 on 2021-04-24 with an amount of 4935.42, and Transaction ID 7815 on 2021-04-17 with an amount of 6044.24.\n", + "Transaction 871054 is a payment transaction that occurred at 2021-02-02 00:00:00. The amount involved in the transaction is 5321.52. The transaction is marked as fraudulent. There are no repeated cards, common merchant transactions, common card transactions, or merchant categories involved in this transaction. The transaction does not have any in-degree or out-degree. The age, city population, occupation, and gender related to this transaction are not specified.\n", + "The average transaction amount for the card 4039101933538921 over the past 6 months is 82.47301270417434.\n", + "The merchant involved in the transaction 871054 is named fraud_Kuhn LLC. This merchant falls under the 'home' category. It has a Pagerank Score of 1.235146 and is part of the community with the ID 13631497. However, the size of this community is 0.\n", + "Yes, there are two activities associated with the transaction 871054 that might be interesting for further investigation. The first activity is a 'Buyer address update', indicating that the buyer has recently moved to another state. The second activity is a 'Card average amount anomaly', suggesting that the transaction amount is significantly larger than the average amount typically spent using the card.\n", + "\n", + "Run 5:\n", + "The transactions from 2/1/21 to 5/1/21 above average amount for that card are as follows: Transaction with id 39843 on 2021-04-17 17:36:29 with amount 7855.36, Transaction with id 40831 on 2021-04-24 23:45:10 with amount 2934.13, Transaction with id 473824 on 2021-04-18 14:29:51 with amount 3713.09, Transaction with id 871054 on 2021-02-02 00:00:00 with amount 5321.52, Transaction with id 769 on 2021-04-17 23:31:10 with amount 2802.55, Transaction with id 7815 on 2021-04-17 16:05:56 with amount 6044.24, Transaction with id 34336 on 2021-04-24 12:24:53 with amount 4935.42.\n", + "Transaction 871054 is a payment transaction that occurred at 00:00:00 on 2021-02-02. The amount of the transaction was 5321.52. This transaction has been flagged as fraudulent. There are no repeated cards, common merchant transactions, or common credit card transactions associated with this transaction. The transaction does not have any merchant category information, age, city population, occupation, or gender associated with it.\n", + "The average transaction amount for the card 4039101933538921 over the past 6 months is 82.47301270417434.\n", + "The merchant involved in the transaction 871054 is named fraud_Kuhn LLC. This merchant falls under the 'home' category. The merchant has a Pagerank Score of 1.235146 and is part of a community with the ID 13631497. However, the size of this community is 0.\n", + "Yes, there are two activities associated with the transaction 871054 that might be interesting for further investigation. The first activity is a 'Buyer address update' indicating that the buyer has recently moved to another state. The second activity is a 'Card average amount anomaly' which suggests that the transaction amount is significantly larger than the average amount typically spent using the card.\n", + "\n", + "Average execution time for question 'Find all transactions, from 2/1/21 to 5/1/21 above average amount for that card. Sort the results.' over 5 runs: 37.3324 seconds\n", + "Average execution time for question 'Provide more details about the transaction 871054.' over 5 runs: 43.4484 seconds\n", + "Average execution time for question 'What is the average transaction amount for the card used 4039101933538921 in this transaction over the past 6 months?' over 5 runs: 20.6316 seconds\n", + "Average execution time for question 'Provide more details about the merchant fraud_Kuhn LLC involved in the transaction 871054' over 5 runs: 24.8842 seconds\n", + "Average execution time for question 'Are there any activities of the user associated with the transaction 871054 that might be interesting to look into for further investigation?' over 5 runs: 35.2934 seconds\n" ] } ], @@ -91,8 +105,8 @@ "\n", "questions = [\n", " \"Find all transactions, from 2/1/21 to 5/1/21 above average amount for that card. Sort the results.\",\n", - " \"Provide more details about the transaction 871054, like the card used and merchant involved in this transaction.\",\n", - " \"What is the average transaction amount for the card used in this transaction over the past 6 months?\",\n", + " \"Provide more details about the transaction 871054.\",\n", + " \"What is the average transaction amount for the card used 4039101933538921 in this transaction over the past 6 months?\",\n", " \"Provide more details about the merchant fraud_Kuhn LLC involved in the transaction 871054\",\n", " \"Are there any activities of the user associated with the transaction 871054 that might be interesting to look into for further investigation?\"\n", "]\n", @@ -108,7 +122,7 @@ " \"query\": question\n", " }\n", "\n", - " res = requests.post(\"http://0.0.0.0:8000/Transaction_Fraud/query_with_history\", \n", + " res = requests.post(\"http://COPILOT_ADDRESS/Transaction_Fraud/query_with_history\", \n", " json=payload, \n", " auth=HTTPBasicAuth(conn.username, conn.password)\n", " )\n", diff --git a/copilot/requirements.txt b/copilot/requirements.txt index 1c333a4d..7689b978 100644 --- a/copilot/requirements.txt +++ b/copilot/requirements.txt @@ -71,6 +71,7 @@ langgraph==0.0.40 langsmith==0.1.24 lxml==4.9.3 marshmallow==3.20.1 +matplotlib==3.9.1 minio==7.2.5 multidict==6.0.4 mypy-extensions==1.0.0 @@ -108,6 +109,7 @@ regex==2023.10.3 requests==2.31.0 rsa==4.9 s3transfer==0.7.0 +scikit-learn==1.5.1 sentry-sdk==1.32.0 setproctitle==1.3.3 shapely==2.0.2