@bigbinary/neeto-form-frontend 1.2.42 → 1.2.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/javascript/src/translations/en.json +2 -1
- package/dist/index.cjs.js +55 -145
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +58 -148
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
|
@@ -77,7 +77,8 @@
|
|
|
77
77
|
"questions": {
|
|
78
78
|
"deleteAlert": {
|
|
79
79
|
"title": "Delete field?",
|
|
80
|
-
"
|
|
80
|
+
"message_one": "You are deleting the <strong>{{label}}</strong> field.",
|
|
81
|
+
"message_other": "You are deleting the <strong>{{label}}</strong> field for all languages."
|
|
81
82
|
},
|
|
82
83
|
"unsavedChangesAlert": {
|
|
83
84
|
"discard": "Discard changes",
|
package/dist/index.cjs.js
CHANGED
|
@@ -643,20 +643,14 @@ var useUpdateForm = function useUpdateForm(options) {
|
|
|
643
643
|
}, _objectSpread$g(_objectSpread$g({}, options), {}, {
|
|
644
644
|
onSuccess: function onSuccess(data, _ref3) {
|
|
645
645
|
var id = _ref3.id;
|
|
646
|
-
queryClient.setQueryData([QUERY_KEYS.QUESTIONS, id, language],
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
});
|
|
651
|
-
queryClient.setQueryData([QUERY_KEYS.QUESTIONS, "preview/".concat(id), language], function (form) {
|
|
652
|
-
return _objectSpread$g(_objectSpread$g({}, form), {}, {
|
|
653
|
-
title: data.title,
|
|
654
|
-
questions: data.questions
|
|
655
|
-
});
|
|
656
|
-
});
|
|
646
|
+
queryClient.setQueryData([QUERY_KEYS.QUESTIONS, id, language], ramda.assoc("title", data.title));
|
|
647
|
+
queryClient.setQueryData([QUERY_KEYS.QUESTIONS, "preview/".concat(id), language], ramda.mergeLeft({
|
|
648
|
+
questions: data.questions,
|
|
649
|
+
title: data.title
|
|
650
|
+
}));
|
|
657
651
|
queryClient.invalidateQueries([QUERY_KEYS.FORMS]);
|
|
658
|
-
queryClient.invalidateQueries([QUERY_KEYS.QUESTIONS, id
|
|
659
|
-
queryClient.invalidateQueries([QUERY_KEYS.QUESTIONS, "preview/".concat(id)
|
|
652
|
+
queryClient.invalidateQueries([QUERY_KEYS.QUESTIONS, id]);
|
|
653
|
+
queryClient.invalidateQueries([QUERY_KEYS.QUESTIONS, "preview/".concat(id)]);
|
|
660
654
|
options.onSuccess && options.onSuccess(data);
|
|
661
655
|
}
|
|
662
656
|
}));
|
|
@@ -674,6 +668,8 @@ var useUpdateQuestions = function useUpdateQuestions(options, language) {
|
|
|
674
668
|
}
|
|
675
669
|
var data = args[0],
|
|
676
670
|
id = args[1].id;
|
|
671
|
+
queryClient.invalidateQueries([QUERY_KEYS.QUESTIONS, id]);
|
|
672
|
+
queryClient.invalidateQueries([QUERY_KEYS.QUESTIONS, "preview/".concat(id)]);
|
|
677
673
|
queryClient.setQueryData([QUERY_KEYS.QUESTIONS, id, language], ramda.assoc("questions", data.questions));
|
|
678
674
|
queryClient.setQueryData([QUERY_KEYS.QUESTIONS, "preview/".concat(id), language], ramda.assoc("questions", data.questions));
|
|
679
675
|
options.onSuccess && options.onSuccess.apply(options, args);
|
|
@@ -752,102 +748,12 @@ var useUpdateSubmission = function useUpdateSubmission(options) {
|
|
|
752
748
|
}));
|
|
753
749
|
};
|
|
754
750
|
|
|
755
|
-
({
|
|
756
|
-
questions: [{
|
|
757
|
-
id: "bb101126-4183-4ddf-adff-7563a2be0b19",
|
|
758
|
-
kind: "paragraph",
|
|
759
|
-
displayOrder: 1,
|
|
760
|
-
displayKind: "Description Field",
|
|
761
|
-
label: i18next.t("neetoForm.common.fillTheFormToChat"),
|
|
762
|
-
placeholder: "",
|
|
763
|
-
isRequired: false,
|
|
764
|
-
options: [],
|
|
765
|
-
nodeId: "bb101126-4183-4ddf-adff-7563a2be0b19"
|
|
766
|
-
}, {
|
|
767
|
-
id: "a8e0178e-44df-465e-8acb-ef5d1c08d541",
|
|
768
|
-
kind: "email",
|
|
769
|
-
displayOrder: 2,
|
|
770
|
-
displayKind: "Email Input Field",
|
|
771
|
-
label: i18next.t("neetoForm.common.email"),
|
|
772
|
-
placeholder: "",
|
|
773
|
-
isRequired: true,
|
|
774
|
-
options: [],
|
|
775
|
-
nodeId: "a8e0178e-44df-465e-8acb-ef5d1c08d541"
|
|
776
|
-
}, {
|
|
777
|
-
id: "a7d3e47d-f7a2-4bf9-aaea-d301ad62d8f6",
|
|
778
|
-
label: i18next.t("neetoForm.common.selectOne"),
|
|
779
|
-
isRequired: false,
|
|
780
|
-
options: [{
|
|
781
|
-
label: "ABC",
|
|
782
|
-
id: "ABC"
|
|
783
|
-
}, {
|
|
784
|
-
label: "EFG",
|
|
785
|
-
id: "EFG"
|
|
786
|
-
}, {
|
|
787
|
-
label: "QWE",
|
|
788
|
-
id: "QWE"
|
|
789
|
-
}],
|
|
790
|
-
kind: "checkbox",
|
|
791
|
-
nodeId: "f32ad8aa-039a-4b70-b3af-b97ed6fc67a6"
|
|
792
|
-
}, {
|
|
793
|
-
id: "a7d3e47d-f7a2-4bf9-aaea-d301ad62wew",
|
|
794
|
-
label: i18next.t("neetoForm.common.rate"),
|
|
795
|
-
isRequired: true,
|
|
796
|
-
highestRatingLabel: "",
|
|
797
|
-
averageRatingLabel: "",
|
|
798
|
-
lowestRatingLabel: "",
|
|
799
|
-
kind: "rating",
|
|
800
|
-
nodeId: "236a8cb3-b86d-4c30-9c18-f0d69788f6bc"
|
|
801
|
-
}, {
|
|
802
|
-
id: "a7d3e47d-f7a2-4bf9-aaea-d301ad62d8as",
|
|
803
|
-
label: i18next.t("neetoForm.common.phone"),
|
|
804
|
-
kind: "phone",
|
|
805
|
-
nodeId: "5dd3be53-ec99-48e2-bf21-298b6108cb00"
|
|
806
|
-
}, {
|
|
807
|
-
id: "a7d3e47d-f7a2-4bf9-aaea-d301ad62d8f32",
|
|
808
|
-
label: i18next.t("neetoForm.common.select"),
|
|
809
|
-
isRequired: false,
|
|
810
|
-
options: [{
|
|
811
|
-
label: "A",
|
|
812
|
-
id: "A"
|
|
813
|
-
}, {
|
|
814
|
-
label: "B",
|
|
815
|
-
id: "B"
|
|
816
|
-
}, {
|
|
817
|
-
label: "C",
|
|
818
|
-
id: "C"
|
|
819
|
-
}],
|
|
820
|
-
kind: "dropdown",
|
|
821
|
-
nodeId: "e65f27ea-a9b9-45b1-a8de-efb27a5b3e72"
|
|
822
|
-
}, {
|
|
823
|
-
id: "a7d3e47d-f7a2-4bf9-aaea-d301ad62d8f8",
|
|
824
|
-
label: "Nice",
|
|
825
|
-
kind: "paragraph",
|
|
826
|
-
nodeId: "15507c92-4bb5-4428-bc2b-0a7b078a144a"
|
|
827
|
-
}, {
|
|
828
|
-
id: "a7d3e47d-f7a2-4bf9-aaea-d301addw2d8f9",
|
|
829
|
-
label: i18next.t("neetoForm.common.singleChoice"),
|
|
830
|
-
isRequired: false,
|
|
831
|
-
options: [{
|
|
832
|
-
label: "A",
|
|
833
|
-
id: "A"
|
|
834
|
-
}, {
|
|
835
|
-
label: "B",
|
|
836
|
-
id: "B"
|
|
837
|
-
}, {
|
|
838
|
-
label: "C",
|
|
839
|
-
id: "C"
|
|
840
|
-
}],
|
|
841
|
-
kind: "radio",
|
|
842
|
-
nodeId: "37683bae-da1b-4890-ade9-0664006dc57d"
|
|
843
|
-
}]
|
|
844
|
-
});
|
|
845
|
-
var QUESTIONS_WITHOUT_FIELD_CODE = ["paragraph", "termsandcondition", "condition", "file_upload"];
|
|
846
|
-
var RESERVED_FIELD_CODES = ["month", "date", "time"];
|
|
847
751
|
var DEFAULT_AVAILABLE_LANGUAGES = [{
|
|
848
752
|
code: "en",
|
|
849
753
|
name: "English"
|
|
850
754
|
}];
|
|
755
|
+
var QUESTIONS_WITHOUT_FIELD_CODE = ["paragraph", "termsandcondition", "condition", "file_upload"];
|
|
756
|
+
var RESERVED_FIELD_CODES = ["month", "date", "time"];
|
|
851
757
|
|
|
852
758
|
function _arrayWithHoles$3(arr) {
|
|
853
759
|
if (Array.isArray(arr)) return arr;
|
|
@@ -9905,8 +9811,7 @@ var useBuildFormState = function useBuildFormState() {
|
|
|
9905
9811
|
};
|
|
9906
9812
|
|
|
9907
9813
|
var ChangeLanguageDropdown = function ChangeLanguageDropdown(_ref) {
|
|
9908
|
-
var
|
|
9909
|
-
initialLanguage = _ref.initialLanguage,
|
|
9814
|
+
var initialLanguage = _ref.initialLanguage,
|
|
9910
9815
|
languages = _ref.languages,
|
|
9911
9816
|
onChange = _ref.onChange;
|
|
9912
9817
|
var _useState = React$2.useState(false),
|
|
@@ -9919,6 +9824,8 @@ var ChangeLanguageDropdown = function ChangeLanguageDropdown(_ref) {
|
|
|
9919
9824
|
setSelectedLanguage = _useState4[1];
|
|
9920
9825
|
var _useTranslation = reactI18next.useTranslation(),
|
|
9921
9826
|
t = _useTranslation.t;
|
|
9827
|
+
var _useFormikContext = formik.useFormikContext(),
|
|
9828
|
+
dirty = _useFormikContext.dirty;
|
|
9922
9829
|
var languageChangeHandler = function languageChangeHandler(code) {
|
|
9923
9830
|
if (!dirty) {
|
|
9924
9831
|
onChange(code);
|
|
@@ -9963,7 +9870,6 @@ var Overview = function Overview(_ref) {
|
|
|
9963
9870
|
description = _ref.description,
|
|
9964
9871
|
availableLanguages = _ref.availableLanguages,
|
|
9965
9872
|
selectedLanguage = _ref.selectedLanguage,
|
|
9966
|
-
dirty = _ref.dirty,
|
|
9967
9873
|
onLanguageChange = _ref.onLanguageChange;
|
|
9968
9874
|
return /*#__PURE__*/React__default["default"].createElement("div", {
|
|
9969
9875
|
className: "mb-4 flex-shrink-0"
|
|
@@ -9975,7 +9881,6 @@ var Overview = function Overview(_ref) {
|
|
|
9975
9881
|
style: "h4",
|
|
9976
9882
|
weight: "semibold"
|
|
9977
9883
|
}, title), availableLanguages.length > 1 && /*#__PURE__*/React__default["default"].createElement(ChangeLanguageDropdown, {
|
|
9978
|
-
dirty: dirty,
|
|
9979
9884
|
initialLanguage: selectedLanguage,
|
|
9980
9885
|
languages: availableLanguages,
|
|
9981
9886
|
onChange: onLanguageChange
|
|
@@ -11655,12 +11560,6 @@ var getAvailableQuestionKinds = function getAvailableQuestionKinds(_ref5) {
|
|
|
11655
11560
|
});
|
|
11656
11561
|
}, allQuestionKinds);
|
|
11657
11562
|
};
|
|
11658
|
-
var sliceLabel = function sliceLabel(label) {
|
|
11659
|
-
if (label && label.length > 23) {
|
|
11660
|
-
return "".concat(label.slice(0, 20), "...");
|
|
11661
|
-
}
|
|
11662
|
-
return label;
|
|
11663
|
-
};
|
|
11664
11563
|
|
|
11665
11564
|
var _path$2, _path2, _path3, _path4, _path5, _path6, _path7;
|
|
11666
11565
|
function _extends$2() { _extends$2 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$2.apply(this, arguments); }
|
|
@@ -11743,7 +11642,6 @@ var _excluded$6 = ["questionKinds", "showAddQuestionDivider", "onValueChange", "
|
|
|
11743
11642
|
function ownKeys$d(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
11744
11643
|
function _objectSpread$d(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$d(Object(t), !0).forEach(function (r) { _defineProperty$6(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$d(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
11745
11644
|
var Form = function Form(_ref) {
|
|
11746
|
-
var _INDEPENDENT_LABELS_M, _questions$deleteQues, _questions$deleteQues2;
|
|
11747
11645
|
var questionKinds = _ref.questionKinds,
|
|
11748
11646
|
showAddQuestionDivider = _ref.showAddQuestionDivider,
|
|
11749
11647
|
onValueChange = _ref.onValueChange,
|
|
@@ -11855,14 +11753,23 @@ var Form = function Form(_ref) {
|
|
|
11855
11753
|
resetForm();
|
|
11856
11754
|
onLanguageChange(code);
|
|
11857
11755
|
};
|
|
11756
|
+
var deleteAlertMessageLabel = function deleteAlertMessageLabel() {
|
|
11757
|
+
var questionKind = questions[deleteQuestionIndex].kind;
|
|
11758
|
+
var independentLabel = INDEPENDENT_LABELS_MAP[questionKind];
|
|
11759
|
+
if (ramda.isNotNil(independentLabel)) return independentLabel;
|
|
11760
|
+
var questionLabel = questions[deleteQuestionIndex].label;
|
|
11761
|
+
if (neetoCist.isNotEmpty(questionLabel)) return neetoCist.truncate(questionLabel, 40);
|
|
11762
|
+
return neetoCist.humanize(questionKind);
|
|
11763
|
+
};
|
|
11858
11764
|
return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(neetoui.Alert, {
|
|
11859
11765
|
isOpen: deleteQuestionIndex !== null,
|
|
11860
11766
|
submitButtonLabel: t("neetoForm.common.delete"),
|
|
11861
11767
|
title: t("neetoForm.questions.deleteAlert.title"),
|
|
11862
|
-
message: /*#__PURE__*/React__default["default"].createElement(reactI18next.Trans, {
|
|
11768
|
+
message: deleteQuestionIndex && /*#__PURE__*/React__default["default"].createElement(reactI18next.Trans, {
|
|
11863
11769
|
i18nKey: "neetoForm.questions.deleteAlert.message",
|
|
11864
11770
|
values: {
|
|
11865
|
-
|
|
11771
|
+
count: availableLanguages.length,
|
|
11772
|
+
label: deleteAlertMessageLabel()
|
|
11866
11773
|
}
|
|
11867
11774
|
}),
|
|
11868
11775
|
onClose: function onClose() {
|
|
@@ -11881,7 +11788,6 @@ var Form = function Form(_ref) {
|
|
|
11881
11788
|
noValidate: true
|
|
11882
11789
|
}), formTitle && /*#__PURE__*/React__default["default"].createElement(Overview, {
|
|
11883
11790
|
availableLanguages: availableLanguages,
|
|
11884
|
-
dirty: dirty,
|
|
11885
11791
|
selectedLanguage: selectedLanguage,
|
|
11886
11792
|
description: formDescription,
|
|
11887
11793
|
title: formTitle,
|
|
@@ -11975,29 +11881,34 @@ var getActiveQuestionKindDetails = function getActiveQuestionKindDetails(_ref) {
|
|
|
11975
11881
|
};
|
|
11976
11882
|
|
|
11977
11883
|
/* eslint-disable @bigbinary/neeto/file-name-and-export-name-standards */
|
|
11978
|
-
var
|
|
11979
|
-
|
|
11980
|
-
field:
|
|
11981
|
-
});
|
|
11982
|
-
return yup.string().required(errorMessage);
|
|
11884
|
+
var requiredLabelValidation = function requiredLabelValidation(schema, field) {
|
|
11885
|
+
return schema.required(i18next__default["default"].t("neetoForm.common.fieldReq", {
|
|
11886
|
+
field: field
|
|
11887
|
+
}));
|
|
11983
11888
|
};
|
|
11984
11889
|
var formValidationSchema = yup.object().shape({
|
|
11985
11890
|
questions: yup.array().of(yup.object().shape({
|
|
11986
|
-
label:
|
|
11987
|
-
is:
|
|
11988
|
-
|
|
11891
|
+
label: yup.string().when("_destroy", {
|
|
11892
|
+
is: true,
|
|
11893
|
+
otherwise: function otherwise(schema) {
|
|
11894
|
+
return schema.when("kind", {
|
|
11895
|
+
is: "paragraph",
|
|
11896
|
+
then: function then(schema) {
|
|
11897
|
+
return schema.required(i18next__default["default"].t("neetoForm.common.paragraphCantBeEmpty"));
|
|
11898
|
+
},
|
|
11899
|
+
otherwise: function otherwise(schema) {
|
|
11900
|
+
return requiredLabelValidation(schema, i18next__default["default"].t("neetoForm.questions.common.questionFields.field.label"));
|
|
11901
|
+
}
|
|
11902
|
+
});
|
|
11903
|
+
}
|
|
11989
11904
|
}),
|
|
11990
11905
|
kind: yup.string().required(),
|
|
11991
11906
|
fieldCode: yup.string().trim().notOneOf(RESERVED_FIELD_CODES, i18next__default["default"].t("neetoForm.error.invalidFieldCode")).when("kind", function (kind, schema) {
|
|
11992
|
-
return QUESTIONS_WITHOUT_FIELD_CODE.includes(kind) ? schema.notRequired() : schema
|
|
11993
|
-
field: i18next__default["default"].t("neetoForm.questions.common.questionFields.field.fieldCode")
|
|
11994
|
-
}));
|
|
11907
|
+
return QUESTIONS_WITHOUT_FIELD_CODE.includes(kind) ? schema.notRequired() : requiredLabelValidation(schema, i18next__default["default"].t("neetoForm.questions.common.questionFields.field.fieldCode"));
|
|
11995
11908
|
}),
|
|
11996
11909
|
optionsAttributes: yup.array().when("kind", function (kind, schema) {
|
|
11997
11910
|
return ["radio", "checkbox", "dropdown"].includes(kind) ? schema.of(yup.object().shape({
|
|
11998
|
-
label:
|
|
11999
|
-
field: i18next__default["default"].t("neetoForm.questions.common.questionFields.field.option")
|
|
12000
|
-
}))
|
|
11911
|
+
label: requiredLabelValidation(yup.string(), i18next__default["default"].t("neetoForm.questions.common.questionFields.field.option"))
|
|
12001
11912
|
})) : schema.notRequired();
|
|
12002
11913
|
}),
|
|
12003
11914
|
highestRatingLabel: yup.string().nullable(),
|
|
@@ -12086,23 +11997,22 @@ var BuildForm = function BuildForm(_ref) {
|
|
|
12086
11997
|
} : _useForm$data,
|
|
12087
11998
|
questions = _useForm$data2.questions,
|
|
12088
11999
|
isQuestionsLoading = _useForm$data2.isQuestionsLoading,
|
|
12089
|
-
isLoading = _useForm.isLoading
|
|
12000
|
+
isLoading = _useForm.isLoading,
|
|
12001
|
+
refetch = _useForm.refetch;
|
|
12090
12002
|
if (isLoading || showLoader && isQuestionsLoading) {
|
|
12091
12003
|
return /*#__PURE__*/React__default["default"].createElement("div", {
|
|
12092
12004
|
className: "flex h-full w-full items-center justify-center py-6"
|
|
12093
12005
|
}, /*#__PURE__*/React__default["default"].createElement(PageLoader__default["default"], null));
|
|
12094
12006
|
}
|
|
12095
|
-
var handleSubmit = function handleSubmit(payload
|
|
12096
|
-
var resetForm = _ref2.resetForm;
|
|
12007
|
+
var handleSubmit = function handleSubmit(payload) {
|
|
12097
12008
|
updateQuestions({
|
|
12098
12009
|
id: id,
|
|
12099
12010
|
values: _objectSpread$c({
|
|
12100
|
-
|
|
12101
|
-
|
|
12102
|
-
})
|
|
12011
|
+
language: selectedLanguage,
|
|
12012
|
+
neetoFormQuestion: payload
|
|
12103
12013
|
}, buildRequestArgs)
|
|
12104
12014
|
}, {
|
|
12105
|
-
onSuccess:
|
|
12015
|
+
onSuccess: refetch
|
|
12106
12016
|
});
|
|
12107
12017
|
};
|
|
12108
12018
|
var onValueChange = function onValueChange(questions) {
|
|
@@ -12115,8 +12025,8 @@ var BuildForm = function BuildForm(_ref) {
|
|
|
12115
12025
|
var isDeletable = isQuestionDeletable !== null && isQuestionDeletable !== void 0 ? isQuestionDeletable : function (question) {
|
|
12116
12026
|
return !nonRemovableFields.includes(question.kind);
|
|
12117
12027
|
};
|
|
12118
|
-
var isRequiredField = isFieldRequired !== null && isFieldRequired !== void 0 ? isFieldRequired : function (
|
|
12119
|
-
var kind =
|
|
12028
|
+
var isRequiredField = isFieldRequired !== null && isFieldRequired !== void 0 ? isFieldRequired : function (_ref2) {
|
|
12029
|
+
var kind = _ref2.kind;
|
|
12120
12030
|
return requiredFields.includes(kind);
|
|
12121
12031
|
};
|
|
12122
12032
|
var isDisabledFieldLabel = isFieldLabelDisabled !== null && isFieldLabelDisabled !== void 0 ? isFieldLabelDisabled : function () {
|
|
@@ -12134,9 +12044,9 @@ var BuildForm = function BuildForm(_ref) {
|
|
|
12134
12044
|
},
|
|
12135
12045
|
validationSchema: formValidationSchema,
|
|
12136
12046
|
onSubmit: handleSubmit
|
|
12137
|
-
}, function (
|
|
12138
|
-
var errors =
|
|
12139
|
-
setFieldError =
|
|
12047
|
+
}, function (_ref3) {
|
|
12048
|
+
var errors = _ref3.errors,
|
|
12049
|
+
setFieldError = _ref3.setFieldError;
|
|
12140
12050
|
return /*#__PURE__*/React__default["default"].createElement(Form, _extends$8({}, _objectSpread$c(_objectSpread$c({}, formDomProps), {}, {
|
|
12141
12051
|
availableLanguages: availableLanguages,
|
|
12142
12052
|
cancelButtonProps: cancelButtonProps,
|