Bin
2025-12-17 262fecaa75b2909ad244f12c3b079ed3ff4ae329
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { isAlive, types } from "mobx-state-tree";
 
import NormalizationMixin from "../mixins/Normalization";
import RegionsMixin from "../mixins/Regions";
import SpanTextMixin from "../mixins/SpanText";
import Utils from "../utils";
import { ParagraphLabelsModel } from "../tags/control/ParagraphLabels";
import { TextAreaModel } from "../tags/control/TextArea/TextArea";
import { ChoicesModel } from "../tags/control/Choices";
import { RatingModel } from "../tags/control/Rating";
import { ParagraphsModel } from "../tags/object/Paragraphs";
import { AreaMixin } from "../mixins/AreaMixin";
import Registry from "../core/Registry";
 
const Model = types
  .model("ParagraphsRegionModel", {
    type: "textrange",
    object: types.late(() => types.reference(ParagraphsModel)),
 
    startOffset: types.integer,
    start: types.string,
    endOffset: types.integer,
    end: types.string,
 
    states: types.maybeNull(types.array(types.union(ParagraphLabelsModel, TextAreaModel, ChoicesModel, RatingModel))),
  })
  .volatile(() => ({
    text: "",
    hideable: true,
  }))
  .views((self) => ({
    get parent() {
      return isAlive(self) ? self.object : null;
    },
    getRegionElement() {
      return self._spans?.[0];
    },
  }))
  .actions((self) => ({
    beforeDestroy() {
      Utils.HTML.removeSpans(self._spans);
    },
 
    setText(text) {
      self.text = text;
    },
 
    fixOffsets(startOffset, endOffset) {
      self.startOffset = startOffset;
      self.endOffset = endOffset;
    },
 
    /**
     * @example
     * {
     *   "value": {
     *     "start": 3,
     *     "end": 5,
     *     "startOffset": 2,
     *     "endOffset": 81,
     *     "paragraphlabels": ["Car"]
     *   }
     * }
     * @typedef {Object} ParagraphsRegionResult
     * @property {Object} value
     * @property {number} value.start index of paragraph where the region starts
     * @property {number} value.end index of paragraph where the region ends
     * @property {number} value.startOffset offset within start paragraph
     * @property {number} value.endOffset offset within end paragraph
     * @property {string} [value.text] text content of the region, can be skipped
     */
 
    /**
     * @return {ParagraphsRegionResult}
     */
    serialize() {
      const { start, end } = self;
 
      const res = {
        value: {
          start,
          end,
          startOffset: self.startOffset,
          endOffset: self.endOffset,
        },
      };
 
      if (self.object.savetextresult === "yes") {
        res.value.text = self.text;
      }
 
      return res;
    },
  }));
 
const ParagraphsRegionModel = types.compose(
  "ParagraphsRegionModel",
  RegionsMixin,
  AreaMixin,
  NormalizationMixin,
  Model,
  SpanTextMixin,
);
 
Registry.addRegionType(ParagraphsRegionModel, "paragraphs");
 
export { ParagraphsRegionModel };