GWM
@ -1,7 +1,7 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"ObsKey": {
|
"ObsKey": {
|
||||||
"CROP": "_T",
|
"CROP": "TOM",
|
||||||
"CROP_TYPE": "SF",
|
"CROP_TYPE": "SF",
|
||||||
"CROP_UNIT": "QUANTITY",
|
"CROP_UNIT": "QUANTITY",
|
||||||
"FREQ": "A",
|
"FREQ": "A",
|
||||||
@ -12,12 +12,12 @@
|
|||||||
"UNIT_MEASURE": "PERCENT"
|
"UNIT_MEASURE": "PERCENT"
|
||||||
},
|
},
|
||||||
"ObsValue": {
|
"ObsValue": {
|
||||||
"Value": "21.6"
|
"Value": "39.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ObsKey": {
|
"ObsKey": {
|
||||||
"CROP": "_T",
|
"CROP": "TOM",
|
||||||
"CROP_TYPE": "SF",
|
"CROP_TYPE": "SF",
|
||||||
"CROP_UNIT": "QUANTITY",
|
"CROP_UNIT": "QUANTITY",
|
||||||
"FREQ": "A",
|
"FREQ": "A",
|
||||||
@ -28,12 +28,12 @@
|
|||||||
"UNIT_MEASURE": "PERCENT"
|
"UNIT_MEASURE": "PERCENT"
|
||||||
},
|
},
|
||||||
"ObsValue": {
|
"ObsValue": {
|
||||||
"Value": "19.3"
|
"Value": "27.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ObsKey": {
|
"ObsKey": {
|
||||||
"CROP": "_T",
|
"CROP": "TOM",
|
||||||
"CROP_TYPE": "SF",
|
"CROP_TYPE": "SF",
|
||||||
"CROP_UNIT": "QUANTITY",
|
"CROP_UNIT": "QUANTITY",
|
||||||
"FREQ": "A",
|
"FREQ": "A",
|
||||||
@ -44,7 +44,583 @@
|
|||||||
"UNIT_MEASURE": "PERCENT"
|
"UNIT_MEASURE": "PERCENT"
|
||||||
},
|
},
|
||||||
"ObsValue": {
|
"ObsValue": {
|
||||||
"Value": "16.98945461"
|
"Value": "26.47654791"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "EGG",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2020",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "63.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "EGG",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2021",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "47.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "EGG",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2022",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "46.81231254"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "SQU",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2020",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "75.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "SQU",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2021",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "78.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "SQU",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2022",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "75.8811408"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "CUC",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2020",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "93.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "CUC",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2021",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "87.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "CUC",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2022",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "85.30071041"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "WAT",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2020",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "1.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "WAT",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2021",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "WAT",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2022",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "1.152487385"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "MEL",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2020",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "30.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "MEL",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2021",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "12.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "MEL",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2022",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "9.008599616"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "PEP",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2020",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "15.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "PEP",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2021",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "15.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "PEP",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2022",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "13.39919274"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "OKR",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2020",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "18.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "OKR",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2021",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "11.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "OKR",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2022",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "8.805405537"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "POT",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2020",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "POT",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2021",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "0.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "POT",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2022",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "0.52456682"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "LEA",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2020",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "41.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "LEA",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2021",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "55.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "LEA",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2022",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "38.7830202"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "ONI",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2020",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "ONI",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2021",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "ONI",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2022",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "2.241648166"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "PUM",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2020",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "PUM",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2021",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "4.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "PUM",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2022",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "6.247409254"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "LET",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2020",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "LET",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2021",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ObsKey": {
|
||||||
|
"CROP": "LET",
|
||||||
|
"CROP_TYPE": "SF",
|
||||||
|
"CROP_UNIT": "QUANTITY",
|
||||||
|
"FREQ": "A",
|
||||||
|
"MEASURE": "TRADE",
|
||||||
|
"REF_AREA": "AE",
|
||||||
|
"SOURCE_DETAIL": "FCSACROP",
|
||||||
|
"TIME_PERIOD": "2022",
|
||||||
|
"UNIT_MEASURE": "PERCENT"
|
||||||
|
},
|
||||||
|
"ObsValue": {
|
||||||
|
"Value": "0.652853161"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
103
main.go
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -448,6 +449,15 @@ func filterDynamicChartData(chartData []map[string]interface{}, keyToFilter, val
|
|||||||
return filteredData
|
return filteredData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateToken() string {
|
||||||
|
bytes := make([]byte, 32)
|
||||||
|
_, err := rand.Read(bytes)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return hex.EncodeToString(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
var app *pocketbase.PocketBase
|
var app *pocketbase.PocketBase
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -571,6 +581,99 @@ func main() {
|
|||||||
return c.File("pb_public/confirm_password_reset.html")
|
return c.File("pb_public/confirm_password_reset.html")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
e.Router.GET("/api/auth/request-password-reset", func(c echo.Context) error {
|
||||||
|
email := c.QueryParam("email")
|
||||||
|
if email == "" {
|
||||||
|
return c.JSON(http.StatusBadRequest, map[string]string{"error": "Email is required"})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find user by email
|
||||||
|
user, err := app.Dao().FindFirstRecordByData("users", "email", email)
|
||||||
|
if err != nil {
|
||||||
|
return c.JSON(http.StatusNotFound, map[string]string{"error": "User not found"})
|
||||||
|
}
|
||||||
|
name := user.GetString("name")
|
||||||
|
// Generate token
|
||||||
|
token := generateToken()
|
||||||
|
expiration := time.Now().Add(30 * time.Minute).UTC()
|
||||||
|
|
||||||
|
// Store token in the database
|
||||||
|
user.Set("pw_reset_token", token)
|
||||||
|
user.Set("pw_reset_token_expiry", expiration)
|
||||||
|
|
||||||
|
if err := app.Dao().SaveRecord(user); err != nil {
|
||||||
|
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "Failed to update user record"})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send email
|
||||||
|
subject := "Reset your FCSC password"
|
||||||
|
resetURL := fmt.Sprintf("%s/api/auth/reset-password?token=%s", baseUrl, token)
|
||||||
|
body := fmt.Sprintf(`
|
||||||
|
<p>Hello,</p>
|
||||||
|
<p>Click on the link below to reset your password.</p>
|
||||||
|
<p>
|
||||||
|
<a href="%s" target="_blank" rel="noopener" style="color: blue; text-decoration: underline;">Reset password</a>
|
||||||
|
</p>
|
||||||
|
<p><i>If you didn't ask to reset your password, you can ignore this email.</i></p>
|
||||||
|
<p>
|
||||||
|
Thanks,<br/>
|
||||||
|
Your App Team<br/>
|
||||||
|
</p>
|
||||||
|
`, resetURL)
|
||||||
|
|
||||||
|
// Create the email message
|
||||||
|
message := &mailer.Message{
|
||||||
|
From: mail.Address{
|
||||||
|
Name: "FCSC",
|
||||||
|
Address: app.Settings().Meta.SenderAddress,
|
||||||
|
},
|
||||||
|
To: []mail.Address{
|
||||||
|
{
|
||||||
|
Name: name,
|
||||||
|
Address: email,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Subject: subject,
|
||||||
|
HTML: body,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the email
|
||||||
|
err = app.NewMailClient().Send(message)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed to send verification email to user: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, map[string]string{"message": "Reset link sent to your email"})
|
||||||
|
})
|
||||||
|
|
||||||
|
e.Router.GET("/api/auth/reset-password", func(c echo.Context) error {
|
||||||
|
token := c.QueryParam("token")
|
||||||
|
if token == "" {
|
||||||
|
return c.JSON(http.StatusBadRequest, map[string]string{"error": "Token is required"})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find user with the token
|
||||||
|
user, err := app.Dao().FindFirstRecordByData("users", "pw_reset_token", token)
|
||||||
|
if err != nil {
|
||||||
|
return c.JSON(http.StatusUnauthorized, map[string]string{"error": "Invalid token"})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert PocketBase `types.DateTime` to `time.Time`
|
||||||
|
expiryTime := user.GetDateTime("pw_reset_token_expiry").Time()
|
||||||
|
log.Printf("expiryTime : '%v'", expiryTime)
|
||||||
|
log.Printf("time.Now : '%v'", time.Now().UTC())
|
||||||
|
if expiryTime.Before(time.Now().UTC()) {
|
||||||
|
return c.File("pb_public/token_expired.html")
|
||||||
|
// return c.JSON(http.StatusUnauthorized, map[string]string{"error": "Token expired"})
|
||||||
|
}
|
||||||
|
|
||||||
|
// return c.JSON(http.StatusOK, map[string]string{"message": "Token is valid"})
|
||||||
|
|
||||||
|
// Serve the reset page
|
||||||
|
return c.File("pb_public/confirm_password_reset.html")
|
||||||
|
})
|
||||||
|
|
||||||
e.Router.GET("/api/login_success", func(c echo.Context) error {
|
e.Router.GET("/api/login_success", func(c echo.Context) error {
|
||||||
|
|
||||||
userID := c.QueryParam("id")
|
userID := c.QueryParam("id")
|
||||||
|
|||||||
BIN
pb_data/data.db
BIN
pb_data/logs.db
|
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"QtQNpYi5me0OVZxMW9h2Zg=="}
|
||||||
|
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"uiU2k7ZNxToo4t8GzxMZpg=="}
|
||||||
|
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"Bd8Ei+2GWlcr7qQbIw2nBA=="}
|
||||||
|
After Width: | Height: | Size: 3.4 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"p4keTgIQ5xOAU8VuKT5dcw=="}
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"07ogwztZgxRY87I+T3YS6w=="}
|
||||||
|
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"uiU2k7ZNxToo4t8GzxMZpg=="}
|
||||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"d+BsCUhtU7PtTiNIG3YEzg=="}
|
||||||
|
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"uiU2k7ZNxToo4t8GzxMZpg=="}
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"QtQNpYi5me0OVZxMW9h2Zg=="}
|
||||||
|
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"Bd8Ei+2GWlcr7qQbIw2nBA=="}
|
||||||
|
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"w0Nm4f4pCYaIpDpuEhQVHg=="}
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"JemDzB+TNQLWrDLe1lxu6g=="}
|
||||||
|
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"w0Nm4f4pCYaIpDpuEhQVHg=="}
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"JemDzB+TNQLWrDLe1lxu6g=="}
|
||||||
|
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":{"original-filename":"male.png"},"md5":"gq2puo4WHB/p8O/dYe6AZA=="}
|
||||||
|
After Width: | Height: | Size: 8.0 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"Ua07BI7xJGVJ7eVStoTK3g=="}
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||||
|
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"uiU2k7ZNxToo4t8GzxMZpg=="}
|
||||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":{"original-filename":"kpi_icon_population.png"},"md5":"BPQklAKzE1awhyRzVAam6A=="}
|
||||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"r8v3ja0ZOKOy5aQ9I7h7CQ=="}
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"QtQNpYi5me0OVZxMW9h2Zg=="}
|
||||||
|
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":{"original-filename":"female.png"},"md5":"LHr3qNvXccxDzGNR1QwAiA=="}
|
||||||
|
After Width: | Height: | Size: 7.5 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"6qNv8XkjaWR5lPp91glyrw=="}
|
||||||
|
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"uiU2k7ZNxToo4t8GzxMZpg=="}
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"QtQNpYi5me0OVZxMW9h2Zg=="}
|
||||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"d+BsCUhtU7PtTiNIG3YEzg=="}
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||||
|
After Width: | Height: | Size: 4.1 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"srBd6fWEm86XwUV6j55geA=="}
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||||
|
After Width: | Height: | Size: 3.4 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"p4keTgIQ5xOAU8VuKT5dcw=="}
|
||||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"mccsVPwG7Fogdc5/VZLFKg=="}
|
||||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"mccsVPwG7Fogdc5/VZLFKg=="}
|
||||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"mccsVPwG7Fogdc5/VZLFKg=="}
|
||||||
|
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"uiU2k7ZNxToo4t8GzxMZpg=="}
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||||
|
After Width: | Height: | Size: 4.1 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"srBd6fWEm86XwUV6j55geA=="}
|
||||||
|
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"uiU2k7ZNxToo4t8GzxMZpg=="}
|
||||||
|
After Width: | Height: | Size: 4.1 KiB |
@ -0,0 +1 @@
|
|||||||
|
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"srBd6fWEm86XwUV6j55geA=="}
|
||||||
52
pb_public/token_expired.html
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Token Expired</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
text-align: center;
|
||||||
|
padding: 50px;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
max-width: 400px;
|
||||||
|
margin: auto;
|
||||||
|
background: white;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
color: #d9534f;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
color: #6c757d;
|
||||||
|
}
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 10px 20px;
|
||||||
|
margin-top: 20px;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #007bff;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.btn:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h1>Token Expired</h1>
|
||||||
|
<p>Sorry, the reset link has expired.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -24,15 +24,20 @@ type GroupByAndSum struct {
|
|||||||
GetTop int `json:"get_top"`
|
GetTop int `json:"get_top"`
|
||||||
Conversion int `json:"conversion"`
|
Conversion int `json:"conversion"`
|
||||||
}
|
}
|
||||||
|
type CountCalculation struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
GetCountOf string `json:"get_count_of"`
|
||||||
|
}
|
||||||
type CardCalculationRequest struct {
|
type CardCalculationRequest struct {
|
||||||
Formula string `json:"formula"`
|
Formula string `json:"formula"`
|
||||||
RecordCount string `json:"record_count"`
|
RecordCount string `json:"record_count"`
|
||||||
RecodeIndex string `json:"record_index"`
|
RecodeIndex string `json:"record_index"`
|
||||||
RecordKey string `json:"record_key"`
|
RecordKey string `json:"record_key"`
|
||||||
AdditionalRecordKey string `json:"additional_record_key"`
|
AdditionalRecordKey string `json:"additional_record_key"`
|
||||||
NumberFormat string `json:"number_format"`
|
NumberFormat string `json:"number_format"`
|
||||||
Conversion string `json:"conversion"`
|
Conversion string `json:"conversion"`
|
||||||
GroupByAndSum GroupByAndSum `json:"groupby_and_sum"`
|
GroupByAndSum GroupByAndSum `json:"groupby_and_sum"`
|
||||||
|
CountCalculation CountCalculation `json:"count_calculation"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func CardCalculation(data []Observation, req CardCalculationRequest) (map[string]string, error) {
|
func CardCalculation(data []Observation, req CardCalculationRequest) (map[string]string, error) {
|
||||||
@ -43,13 +48,24 @@ func CardCalculation(data []Observation, req CardCalculationRequest) (map[string
|
|||||||
|
|
||||||
var selectedData []Observation
|
var selectedData []Observation
|
||||||
if req.RecodeIndex != "" {
|
if req.RecodeIndex != "" {
|
||||||
// Convert RecodeIndex to an integer
|
|
||||||
index, err := strconv.Atoi(req.RecodeIndex)
|
if req.RecodeIndex == "last" {
|
||||||
if err != nil || index < 0 || index >= len(data) {
|
index := len(data)
|
||||||
// return nil, errors.New("invalid record index")
|
if index < 0 || index >= len(data) {
|
||||||
selectedData = []Observation{}
|
selectedData = []Observation{}
|
||||||
|
} else {
|
||||||
|
selectedData = []Observation{data[index]}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
selectedData = []Observation{data[index]}
|
// Convert RecodeIndex to an integer
|
||||||
|
index, err := strconv.Atoi(req.RecodeIndex)
|
||||||
|
if err != nil || index < 0 || index >= len(data) {
|
||||||
|
selectedData = []Observation{}
|
||||||
|
} else {
|
||||||
|
selectedData = []Observation{data[index]}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -132,6 +148,32 @@ func CardCalculation(data []Observation, req CardCalculationRequest) (map[string
|
|||||||
} else {
|
} else {
|
||||||
fmt.Println("No observations returned from CalculateGroupedSum")
|
fmt.Println("No observations returned from CalculateGroupedSum")
|
||||||
}
|
}
|
||||||
|
case "count_calculation":
|
||||||
|
countCalculationReq := req.CountCalculation
|
||||||
|
|
||||||
|
var cardCountCalculationRequest CountCalculation
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(countCalculationReq)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(jsonData, &cardCountCalculationRequest)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedData, err = CalculateCount(selectedData, cardCountCalculationRequest)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(selectedData) > 0 {
|
||||||
|
result = float64(len(selectedData))
|
||||||
|
selectedData = selectedData[:1]
|
||||||
|
} else {
|
||||||
|
fmt.Println("No observations returned from CalculateGroupedSum")
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("invalid formula")
|
return nil, errors.New("invalid formula")
|
||||||
@ -200,17 +242,26 @@ func average(data []Observation) float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func highest(data []Observation) float64 {
|
func highest(data []Observation) float64 {
|
||||||
|
if len(data) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
max := getFloatValue(data[0].ObsValue.Value)
|
max := getFloatValue(data[0].ObsValue.Value)
|
||||||
for _, obs := range data {
|
for _, obs := range data[1:] {
|
||||||
val := getFloatValue(obs.ObsValue.Value)
|
val := getFloatValue(obs.ObsValue.Value)
|
||||||
if val > max {
|
if val > max {
|
||||||
max = val
|
max = val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return max
|
return max
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lowest(data []Observation) float64 {
|
func lowest(data []Observation) float64 {
|
||||||
|
if len(data) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
min := getFloatValue(data[0].ObsValue.Value)
|
min := getFloatValue(data[0].ObsValue.Value)
|
||||||
for _, obs := range data {
|
for _, obs := range data {
|
||||||
val := getFloatValue(obs.ObsValue.Value)
|
val := getFloatValue(obs.ObsValue.Value)
|
||||||
@ -315,7 +366,7 @@ func applyConversion(value float64, conversion string, numberFormat string) stri
|
|||||||
case "%":
|
case "%":
|
||||||
return formatNumber(value, "%")
|
return formatNumber(value, "%")
|
||||||
default:
|
default:
|
||||||
return formatNumber(value, "")
|
return formatNumber(value, conversion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +408,23 @@ func extractRecordKeyValue(data []Observation, key string, additionalkey string,
|
|||||||
}
|
}
|
||||||
return val1
|
return val1
|
||||||
}
|
}
|
||||||
|
case "count_calculation":
|
||||||
|
for _, obs := range data {
|
||||||
|
|
||||||
|
if val, exists := obs.ObsKey[key]; exists {
|
||||||
|
|
||||||
|
// Check if additionalkey exists in obs.ObsKey
|
||||||
|
if val2, exists2 := obs.ObsKey[additionalkey]; exists2 {
|
||||||
|
|
||||||
|
return val + " - " + val2
|
||||||
|
} else {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -658,3 +725,43 @@ func FilterByMultipleKeys(data []Observation, filters []Filter) ([]Observation,
|
|||||||
|
|
||||||
return filteredData, nil
|
return filteredData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------- Count Calculation -------------------------------------------------
|
||||||
|
|
||||||
|
func CalculateCount(observations []Observation, request CountCalculation) ([]Observation, error) {
|
||||||
|
|
||||||
|
if request.GetCountOf == "highest" || request.GetCountOf == "lowest" {
|
||||||
|
var extremeValue int
|
||||||
|
var filteredObservations []Observation
|
||||||
|
first := true
|
||||||
|
isHighest := request.GetCountOf == "highest"
|
||||||
|
|
||||||
|
for _, obs := range observations {
|
||||||
|
if valStr, exists := obs.ObsKey[request.Key]; exists {
|
||||||
|
val, err := strconv.Atoi(valStr)
|
||||||
|
if err != nil {
|
||||||
|
continue // Skip if conversion fails
|
||||||
|
}
|
||||||
|
|
||||||
|
if first || (isHighest && val > extremeValue) || (!isHighest && val < extremeValue) {
|
||||||
|
extremeValue = val
|
||||||
|
first = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter observations that match the extreme value
|
||||||
|
for _, obs := range observations {
|
||||||
|
if valStr, exists := obs.ObsKey[request.Key]; exists {
|
||||||
|
val, err := strconv.Atoi(valStr)
|
||||||
|
if err == nil && val == extremeValue {
|
||||||
|
filteredObservations = append(filteredObservations, obs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filteredObservations, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("unsupported get_count_of value: %s", request.GetCountOf)
|
||||||
|
}
|
||||||
|
|||||||