"use strict";

exports.__esModule = true;
exports["default"] = void 0;

var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));

var _react = _interopRequireWildcard(require("react"));

var _reactRedux = require("react-redux");

require("@mediapipe/pose");

var _camera_utils = require("@mediapipe/camera_utils");

var poseDetection = _interopRequireWildcard(require("@tensorflow-models/pose-detection"));

var knnClassifier = _interopRequireWildcard(require("@tensorflow-models/knn-classifier"));

var tf = _interopRequireWildcard(require("@tensorflow/tfjs-core"));

require("@tensorflow/tfjs-backend-cpu");

var _InstructionalVideo = _interopRequireDefault(require("./InstructionalVideo"));

var _EndScreen = _interopRequireDefault(require("./EndScreen"));

var _TemplateTimer = _interopRequireDefault(require("../components/TemplateTimer"));

var _TemplateCountDownReps = _interopRequireDefault(require("../components/TemplateCountDownReps"));

var _TemplateCountDownSets = _interopRequireDefault(require("../components/TemplateCountDownSets"));

var _TransitionCalibration = _interopRequireDefault(require("../components/TransitionCalibration"));

var _TransitionCountDown = _interopRequireDefault(require("../components/TransitionCountDown"));

var _main = require("../store/performance/main");

var _data = require("./data");

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

function _extends() { _extends = Object.assign || 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.apply(this, arguments); }

var _initialPoseConfidence = {
  down: 0,
  up: 0
};

var _poseConfidence = _extends({}, _initialPoseConfidence);

var _last = null;
var _numberOfReps = 0;
var _calibration = false; // const _limit = 0.9;

var _legsLimit = 0.5;

var Main = function Main(props) {
  var dispatch = (0, _reactRedux.useDispatch)();

  var _useSelector = (0, _reactRedux.useSelector)(function (state) {
    return state.performance.main;
  }),
      exerciseProgress = _useSelector.exerciseProgress,
      complete = _useSelector.complete,
      currentExercise = _useSelector.currentExercise,
      identifier = _useSelector.identifier,
      user = _useSelector.user;

  var videoRef = (0, _react.useRef)(null);
  var timerRef = (0, _react.useRef)(null);

  var _useState = (0, _react.useState)(knnClassifier.create()),
      classifier = _useState[0];

  var _useState2 = (0, _react.useState)(false),
      calibration = _useState2[0],
      setCalibration = _useState2[1];

  var _useState3 = (0, _react.useState)(false),
      showCountDown = _useState3[0],
      setShowCountDown = _useState3[1];

  var poseEstimator = /*#__PURE__*/function () {
    var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator["default"].mark(function _callee2() {
      var detector, camera;
      return _regenerator["default"].wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              _context2.prev = 0;
              _context2.next = 3;
              return poseDetection.createDetector(poseDetection.SupportedModels.BlazePose, {
                runtime: 'mediapipe',
                modelType: 'heavy',
                solutionPath: 'https://cdn.jsdelivr.net/npm/@mediapipe/pose',
                width: 1280,
                height: 720
              });

            case 3:
              detector = _context2.sent;
              camera = new _camera_utils.Camera(videoRef.current, {
                onFrame: function () {
                  var _onFrame = _asyncToGenerator( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
                    var poses, poseList, _iterator, _step, keypoint, ans;

                    return _regenerator["default"].wrap(function _callee$(_context) {
                      while (1) {
                        switch (_context.prev = _context.next) {
                          case 0:
                            _context.next = 2;
                            return detector.estimatePoses(videoRef.current);

                          case 2:
                            poses = _context.sent;

                            if (!(poses.length > 0 && !showCountDown)) {
                              _context.next = 14;
                              break;
                            }

                            poseList = [];

                            for (_iterator = _createForOfIteratorHelperLoose(poses[0].keypoints); !(_step = _iterator()).done;) {
                              keypoint = _step.value;

                              if (_data.keypoints[keypoint.name] === 23 || _data.keypoints[keypoint.name] === 24 || _data.keypoints[keypoint.name] === 25 || _data.keypoints[keypoint.name] === 26 || _data.keypoints[keypoint.name] === 27 || _data.keypoints[keypoint.name] === 28 || _data.keypoints[keypoint.name] === 31 || _data.keypoints[keypoint.name] === 32) {
                                _calibration = keypoint.score > 0.2;
                                poseList.push(keypoint.x, keypoint.y);
                              }
                            } // VERIFICAR PERFORMANCE


                            setCalibration(_calibration);

                            if (!_calibration) {
                              _context.next = 14;
                              break;
                            }

                            _context.next = 10;
                            return classifier.predictClass(tf.tensor1d(poseList), 2);

                          case 10:
                            ans = _context.sent;
                            if (ans.confidences.down > 0.5) console.log('DOWN', _numberOfReps);
                            if (ans.confidences.up > 0.5) console.log('UP', _numberOfReps);

                            if (ans.confidences.down > 0.5 || ans.confidences.up > 0.5) {
                              if (_poseConfidence[ans.label] < _data.enterThreshold || _poseConfidence[ans.label] < _data.exitThreshold) {
                                _poseConfidence[ans.label] += ans.confidences[ans.label];
                              }

                              if (_poseConfidence.down >= _data.exitThreshold && _poseConfidence.up >= _data.enterThreshold) {
                                _numberOfReps += 1;
                                _poseConfidence = _extends({}, _initialPoseConfidence);
                                dispatch((0, _main.setNumberOfReps)(_numberOfReps));
                              }

                              if (_poseConfidence.down <= _data.exitThreshold && _poseConfidence.up <= _data.enterThreshold && _last !== ans.label) {
                                _poseConfidence = _extends({}, _initialPoseConfidence);
                              }

                              _last = ans.label;
                            }

                          case 14:
                          case "end":
                            return _context.stop();
                        }
                      }
                    }, _callee);
                  }));

                  function onFrame() {
                    return _onFrame.apply(this, arguments);
                  }

                  return onFrame;
                }(),
                width: 1280,
                height: 720
              });
              _context2.next = 7;
              return camera.start();

            case 7:
              setShowCountDown(true);
              _context2.next = 13;
              break;

            case 10:
              _context2.prev = 10;
              _context2.t0 = _context2["catch"](0);
              console.log('🚀 ~ file: App.js ~ line 35 ~ poseEstimator ~ error', _context2.t0);

            case 13:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, null, [[0, 10]]);
    }));

    return function poseEstimator() {
      return _ref.apply(this, arguments);
    };
  }();

  var knnTensor = function knnTensor() {
    _data.down.forEach(function (data) {
      var keypointsSelected = [];

      for (var _i = 0, _Object$entries = Object.entries(_data.keypoints); _i < _Object$entries.length; _i++) {
        var _Object$entries$_i = _Object$entries[_i],
            index = _Object$entries$_i[1];

        if (index === _data.keypoints['left_hip'] || index === _data.keypoints['right_hip'] || index === _data.keypoints['left_knee'] || index === _data.keypoints['right_knee'] || index === _data.keypoints['left_ankle'] || index === _data.keypoints['right_ankle'] || index === _data.keypoints['left_foot_index'] || index === _data.keypoints['right_foot_index']) {
          var keypoint = _data.numbersToRecord[index];
          keypointsSelected.push(data[keypoint.x], data[keypoint.y]);
        }
      }

      classifier.addExample(tf.tensor1d(keypointsSelected), 'down');
    });

    _data.up.forEach(function (data) {
      var keypointsSelected = [];

      for (var _i2 = 0, _Object$entries2 = Object.entries(_data.keypoints); _i2 < _Object$entries2.length; _i2++) {
        var _Object$entries2$_i = _Object$entries2[_i2],
            index = _Object$entries2$_i[1];

        if (index === _data.keypoints['left_hip'] || index === _data.keypoints['right_hip'] || index === _data.keypoints['left_knee'] || index === _data.keypoints['right_knee'] || index === _data.keypoints['left_ankle'] || index === _data.keypoints['right_ankle'] || index === _data.keypoints['left_foot_index'] || index === _data.keypoints['right_foot_index']) {
          var keypoint = _data.numbersToRecord[index];
          keypointsSelected.push(data[keypoint.x], data[keypoint.y]);
        }
      }

      classifier.addExample(tf.tensor1d(keypointsSelected), 'up');
    });
  };

  (0, _react.useEffect)(function () {
    if (exerciseProgress.current >= (currentExercise === null || currentExercise === void 0 ? void 0 : currentExercise.repetitions) && exerciseProgress.sets <= (currentExercise === null || currentExercise === void 0 ? void 0 : currentExercise.setsPerSessions)) {
      _numberOfReps = 0;
      dispatch((0, _main.setNumberOfSets)());
      setShowCountDown(true);
    }
  }, [exerciseProgress]);
  (0, _react.useEffect)(function () {
    if (complete) {
      dispatch((0, _main.saveUserProgress)({
        identifier: identifier,
        user: user,
        exercise: currentExercise._id,
        time: timerRef.current.state.time
      }));
      dispatch((0, _main.resetAll)());
    }
  }, [complete]);
  (0, _react.useEffect)(function () {
    poseEstimator(knnTensor());
  }, []);
  return complete ? /*#__PURE__*/_react["default"].createElement(_EndScreen["default"], null) : /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(_InstructionalVideo["default"], null), /*#__PURE__*/_react["default"].createElement(_TemplateCountDownReps["default"], {
    countProgress: exerciseProgress
  }), /*#__PURE__*/_react["default"].createElement(_TemplateCountDownSets["default"], {
    countProgress: exerciseProgress
  }), showCountDown && /*#__PURE__*/_react["default"].createElement(_TransitionCountDown["default"], {
    callback: function callback() {
      return setShowCountDown(false);
    }
  }), !calibration && /*#__PURE__*/_react["default"].createElement(_TransitionCalibration["default"], {
    currentExercise: currentExercise
  }), /*#__PURE__*/_react["default"].createElement(_TemplateTimer["default"], {
    reference: timerRef
  }), /*#__PURE__*/_react["default"].createElement("video", {
    ref: videoRef
  }));
};

var _default = (0, _react.memo)(Main);

exports["default"] = _default;
module.exports = exports.default;