Esempio n. 1
0
 /** Remove this sessions's user node. */
 public void logout() {
   if (userHandle != null) {
     try {
       // Invoke User.onLogout() iff this is a transactor request with a request
       // evaluator already associated (i.e., if this is called from an app/script).
       // Otherwise, we assume being called from the scheduler thread, which takes
       // care of calling User.onLogout().
       RequestEvaluator reval = app.getCurrentRequestEvaluator();
       if (reval != null) {
         Node userNode = userHandle.getNode(app.nmgr.safe);
         if (userNode != null)
           reval.invokeDirectFunction(userNode, "onLogout", new Object[] {sessionId});
       }
     } catch (Exception x) {
       // errors should already be logged by request evaluator, but you never know
       app.logError("Error in onLogout", x);
     } finally {
       // do log out
       userHandle = null;
       uid = null;
       lastModified = System.currentTimeMillis();
       modifiedInRequest = true;
     }
   }
 }
Esempio n. 2
0
  public void render(FacesContext context) throws FacesException {
    if (context.getResponseComplete()) return;

    Application app = context.getApplication();
    ViewHandler view = app.getViewHandler();

    beforePhase(context, PhaseId.RENDER_RESPONSE);

    try {
      if (log.isLoggable(Level.FINER)) log.finer(context.getViewRoot() + " before render view");

      view.renderView(context, context.getViewRoot());
    } catch (java.io.IOException e) {
      if (sendError(context, "renderView", e)) return;

      throw new FacesException(e);
    } catch (RuntimeException e) {
      if (sendError(context, "renderView", e)) return;

      throw e;
    } finally {
      afterPhase(context, PhaseId.RENDER_RESPONSE);

      logMessages(context);
    }
  }
 public void actionPerformed(ActionEvent ae) {
   String cmd = ae.getActionCommand();
   if (JOkCancelPanel.OK.equals(cmd)) {
     // update evaluator
     evaluator.name = tfName.getText();
     evaluator.type = (byte) cbType.getSelectedIndex();
     evaluator.ignoreDiagonals = cbDiagonals.isSelected();
     evaluator.investments = (byte) cbInvestment.getSelectedIndex();
     evaluator.orgFile = orgFile;
     setVisible(false);
   } else if (JOkCancelPanel.CANCEL.equals(cmd)) {
     // don't update evaluator
     setVisible(false);
   } else if (CMD_CHOOSE_FILE.equals(cmd)) {
     // get a file dialog
     JFrame f = new JFrame();
     JFileChooser jfc = Application.getFileChooser();
     int res = jfc.showOpenDialog(f);
     Application.setWorkingDirectory(jfc.getCurrentDirectory());
     if (res == JFileChooser.CANCEL_OPTION) {
       return;
     }
     orgFile = jfc.getSelectedFile();
     lOrgFileName.setText("File: " + orgFile.getName());
   }
 }
Esempio n. 4
0
 public static void runOnEventThread(Runnable r) {
   if (Application.isEventDispatchThread()) {
     r.run();
   } else {
     Application.getApplication().invokeLater(r);
   }
 }
Esempio n. 5
0
  private void restoreView(FacesContext context) throws FacesException {
    Application app = context.getApplication();

    if (app instanceof ApplicationImpl) ((ApplicationImpl) app).initRequest();

    ViewHandler view = app.getViewHandler();

    view.initView(context);

    UIViewRoot viewRoot = context.getViewRoot();

    if (viewRoot != null) {
      ExternalContext extContext = context.getExternalContext();

      viewRoot.setLocale(extContext.getRequestLocale());

      doSetBindings(context.getELContext(), viewRoot);

      return;
    }

    String viewId = calculateViewId(context);

    String renderKitId = view.calculateRenderKitId(context);

    RenderKitFactory renderKitFactory =
        (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);

    RenderKit renderKit = renderKitFactory.getRenderKit(context, renderKitId);

    ResponseStateManager stateManager = renderKit.getResponseStateManager();

    if (stateManager.isPostback(context)) {
      viewRoot = view.restoreView(context, viewId);

      if (viewRoot != null) {
        doSetBindings(context.getELContext(), viewRoot);
      } else {
        // XXX: backward compat issues with ViewHandler and StateManager

        // throw new ViewExpiredException(L.l("{0} is an expired view", viewId));

        context.renderResponse();

        viewRoot = view.createView(context, viewId);

        context.setViewRoot(viewRoot);
      }

      context.setViewRoot(viewRoot);
    } else {
      context.renderResponse();

      viewRoot = view.createView(context, viewId);

      context.setViewRoot(viewRoot);
    }
  }
Esempio n. 6
0
  public static void main(String[] args) {
    Application app = new Application();

    mSelfNodeID = Integer.parseInt(args[0]);
    mConfigFile = args[1];
    mConfigReader = new ConfigReader(mConfigFile);
    app.initializeArrays();

    /* create server to receive messages*/
    mServer =
        new SctpServer(
            app,
            mConfigReader.getNodeConfig(mSelfNodeID)[0],
            mConfigReader.getNodeConfig(mSelfNodeID)[1],
            mConfigReader.getNodeConfig(mSelfNodeID)[2],
            mConfigReader.getNodeCount() - 1);
    mServerThread = new Thread(mServer);
    mServerThread.start();

    // Timer to indicate when to request CS entry
    TimerThread timer = new TimerThread(app);
    new Thread(timer).start();

    // Create a communication channel to every other node
    for (int i = 0; i < mConfigReader.getNodeCount(); i++) {
      if (i != mSelfNodeID) {
        SocketAddress mSocketAddress =
            new InetSocketAddress(
                mConfigReader.getNodeConfig(i)[1],
                Integer.parseInt(mConfigReader.getNodeConfig(i)[2]));
        MessageInfo mMessageInfo = MessageInfo.createOutgoing(null, 0);

        try {

          SctpChannel mSctpChannel = SctpChannel.open();
          mSctpChannel.connect(mSocketAddress);
          ByteBuffer mByteBuffer = ByteBuffer.allocate(MESSAGE_SIZE);
          mByteBuffer.put("test".getBytes());
          mByteBuffer.flip();
          mSctpChannel.send(mByteBuffer, mMessageInfo);
        } catch (Exception e) {
          System.out.println("Exception: " + e);
        }
      }
    }

    app.applicationModule();

    app.testCorrectness();

    System.exit(0);
  }
Esempio n. 7
0
 /** Gets the user Node from this Application's NodeManager. */
 public INode getUserNode() {
   if (userHandle != null) {
     return userHandle.getNode(app.getWrappedNodeManager());
   } else {
     return null;
   }
 }
Esempio n. 8
0
 /**
  * Try logging in this session given the userName and password.
  *
  * @param userName the user name
  * @param password the password
  * @return true if session was logged in.
  */
 public boolean login(String userName, String password) {
   if (app.loginSession(userName, password, this)) {
     lastModified = System.currentTimeMillis();
     modifiedInRequest = true;
     return true;
   }
   return false;
 }
Esempio n. 9
0
  @Override
  protected UIComponent createComponent(FacesContext context, String newId) throws JspException {
    Application app = context.getApplication();

    UIComponent component;

    if (_binding != null) {
      component = app.createComponent(_binding, context, getComponentType());
      component.setValueExpression("binding", _binding);
    } else component = app.createComponent(getComponentType());

    component.setId(getId());

    setProperties(component);

    return component;
  }
  protected void respondAdmin(HttpServletRequest req, HttpServletResponse res) throws IOException {
    res.setContentType("text/xml");
    StringBuffer buf = new StringBuffer();

    String _details = req.getParameter("details");
    boolean details = (_details != null && _details.equals("1"));

    ConnectionGroup.dumpGroupsXML(buf, details);

    String appName = req.getParameter("application");
    if (appName != null && !appName.equals("")) {
      if (appName.equals("*")) {
        Application.dumpApplicationsXML(buf, details);
      } else {
        Application application = Application.getApplication(appName, false);
        if (application != null) application.toString();
      }
    }

    ConnectionAgent.dumpAgentsXML(buf, details);

    ServletOutputStream out = res.getOutputStream();
    try {
      out.println(
          "<connection-info "
              + " max-message-length=\""
              + HTTPConnection.getMaxMessageLen()
              + "\""
              + " connection-length=\""
              + HTTPConnection.getConnectionLength()
              + "\""
              + " reconnection-wait-interval=\""
              + HTTPConnection.getReconnectionWaitInterval()
              + "\""
              + " >");
      out.println(buf.toString());
      out.println("</connection-info>");
    } finally {
      FileUtils.close(out);
    }
  }
Esempio n. 11
0
  /**
   * REST endpoint returns a json array containing metadata about the currently logged in user's
   * uploaded files.
   *
   * @return json containing file upload ids and filenames
   */
  public Result listUploads() {
    List<UserUpload> uploadList = UserUpload.findUploadsByUserId(Application.getCurrentUserId());

    ObjectNode response = Json.newObject();
    ArrayNode uploads = response.putArray("uploads");

    for (UserUpload userUpload : uploadList) {
      ObjectNode upload = Json.newObject();
      upload.put("id", userUpload.id);
      upload.put("filename", userUpload.fileName);
      uploads.add(upload);
    }

    return ok(uploads);
  }
Esempio n. 12
0
  private static void startStream(List<String> terms) throws TwitterException {
    if (twitter != null) {
      twitter.cleanUp();
    }
    if (esClient != null) {
      esClient.close();
      esClient = null;
    }

    play.Configuration pconf = Play.application().configuration();
    String elasticSearchCluster = pconf.getString("tweet.elasticsearch.cluster.name");
    if (elasticSearchCluster != null) {
      Logger.info("Configuring ElasticSearch...");
      Settings settings =
          ImmutableSettings.settingsBuilder().put("cluster.name", elasticSearchCluster).build();

      esClient =
          new TransportClient(settings)
              .addTransportAddress(
                  new InetSocketTransportAddress(
                      pconf.getString("tweet.elasticsearch.transport.host"),
                      pconf.getInt("tweet.elasticsearch.transport.port")));
    } else {
      esClient = null;
    }

    twitter4j.conf.Configuration tconf = Application.getTwitterConfiguration();
    TwitterStreamFactory tf = new TwitterStreamFactory(tconf);
    twitter = tf.getInstance();
    StatusListener l =
        new TweetListener(
            terms,
            esClient,
            pconf.getString("tweet.elasticsearch.index"),
            pconf.getString("tweet.elasticsearch.type"));
    twitter.addListener(l);

    String[] tracks = new String[terms.size()];
    StringBuffer termsString = new StringBuffer();
    for (int i = 0; i < terms.size(); i++) {
      tracks[i] = terms.get(i);
      if (i != 0) termsString.append(",");
      termsString.append(terms.get(i));
    }
    FilterQuery q = new FilterQuery().track(tracks);
    twitter.filter(q);
    Logger.info("Starting listening for tweets using terms " + termsString.toString() + "...");
  }
Esempio n. 13
0
  private void processPushMessage(final byte[] data) {
    Application.getApplication()
        .invokeLater(
            new Runnable() {
              public void run() {
                String msg = new String(data);
                LOG.TRACE("Triger sync on PUSH message [" + msg + " ]\n");

                String[] op;
                String[] ops = split(msg, "\n");
                for (int loop = 0; loop < ops.length; loop++) {
                  if (ops[loop].startsWith("do_sync")) {
                    op = splitOnce(ops[loop], "=");
                    if (op.length <= 1 || "all".equalsIgnoreCase(op[1])) {
                      SyncThread.doSyncAllSources();
                    } else if ((op[1] != null) && (op[1].length() > 0)) {
                      SyncThread.doSyncSource(op[1].trim());
                    }
                  } else if (ops[loop].startsWith("show_popup")) {
                    op = splitOnce(ops[loop], "=");
                    if (op.length > 1) {
                      showPopup(op[1]);
                    }
                  } else if (ops[loop].startsWith("vibrate")) {
                    op = splitOnce(ops[loop], "=");
                    if (op.length > 1) {
                      vibrate(op[1]);
                    } else {
                      vibrate("2500");
                    }
                  } else if (ops[loop].startsWith("play_file")) {
                    op = splitOnce(ops[loop], "=");
                    if (op.length > 1) {
                      op = splitOnce(op[1], ",");
                      if (op.length > 1) {
                        play_file(op[0], op[1]);
                      } else {
                        play_file(op[0], null);
                      }
                    }
                  }
                }
              }
            });
  }
Esempio n. 14
0
  /**
   * Helper method creates a temp file from the multipart form data and persists the upload file
   * metadata to the database
   *
   * @param filePart data from the form submission
   * @return an instance of UploadFile that has been persisted to the db
   */
  private static UserUpload uploadFile(Http.MultipartFormData.FilePart filePart) {
    File src = (File) filePart.getFile();
    File file = null;
    try {
      file = File.createTempFile(filePart.getFilename() + "-", ".csv");
      FileUtils.copyFile(src, file);
    } catch (IOException e) {
      throw new RuntimeException("Could not create temp file for upload", e);
    }

    UserUpload uploadFile = new UserUpload();
    uploadFile.absolutePath = file.getAbsolutePath();
    uploadFile.fileName = filePart.getFilename();
    uploadFile.user = Application.getCurrentUser();
    uploadFile.save();

    return uploadFile;
  }
Esempio n. 15
0
  public void OpenFileToolbar() {
    JFileChooser fileChooser = new JFileChooser();
    int returnVal = fileChooser.showOpenDialog(this);
    if (returnVal == JFileChooser.APPROVE_OPTION) {
      File file = fileChooser.getSelectedFile();
      try {
        opentFile(file.getPath());

        Workspaces workspaces = Application.getInstance().getWorkspaces();
        Map<String, Workspaces.ViewFrame> frames = workspaces.getOpenFrames();
        Object[] objFrames = frames.values().toArray();
        ViewFrame[] viewFrames = new ViewFrame[objFrames.length];
        for (int i = 0; i < objFrames.length; i++) {
          viewFrames[i] = (ViewFrame) objFrames[i];
          if (viewFrames[i].isSelected()) viewFrames[i].setTitle(file.getPath());
        }
      } catch (Exception ex) {
        ex.printStackTrace();
      }
    }
  }
Esempio n. 16
0
  Application(Application app) {
    this.lambda = copy(app.getLambda());
    this.exp = copy(app.getExpression());

    copyEnvironment(app);
  }
Esempio n. 17
0
  /**
   * The alt-dd element specifies a URI to the post-assembly deployment descriptor relative to the
   * root of the application
   *
   * @param descriptor the Application deployment descriptor
   * @return <code>Result</code> the results for this assertion
   */
  public Result check(Application descriptor) {

    Result result = getInitializedResult();
    if (descriptor.getEjbBundleDescriptors().size() > 0) {
      boolean oneFailed = false;
      int na = 0;
      for (Iterator itr = descriptor.getEjbBundleDescriptors().iterator(); itr.hasNext(); ) {
        EjbBundleDescriptor ejbd = (EjbBundleDescriptor) itr.next();

        if (ejbd.getModuleDescriptor().getAlternateDescriptor() != null) {
          if (!(ejbd.getModuleDescriptor().getAlternateDescriptor().equals(""))) {
            JarFile jarFile = null;
            InputStream deploymentEntry = null;
            //                        File f = null;
            //                        if (Verifier.getEarFile() != null)
            //                            f = new File(Verifier.getEarFile());

            try {
              //                            if (f==null){
              String uri = getAbstractArchiveUri(descriptor);
              //                                try {
              FileArchive arch = new FileArchive();
              arch.open(uri);
              deploymentEntry = arch.getEntry(ejbd.getModuleDescriptor().getAlternateDescriptor());
              //                                }catch (Exception e) { }
              //                            }else{
              //
              //                                jarFile = new JarFile(f);
              //                                ZipEntry deploymentEntry1 =
              // jarFile.getEntry(ejbd.getModuleDescriptor().getAlternateDescriptor());
              //                                if (deploymentEntry1 != null){
              //                                    deploymentEntry =
              // jarFile.getInputStream(deploymentEntry1);
              //                                }
              //                            }

              if (deploymentEntry != null) {
                result.addGoodDetails(
                    smh.getLocalString(
                        getClass().getName() + ".passed",
                        "Found alternate EJB deployment descriptor URI file [ {0} ] within [ {1} ]",
                        new Object[] {
                          ejbd.getModuleDescriptor().getAlternateDescriptor(), ejbd.getName()
                        }));
              } else {
                if (!oneFailed) {
                  oneFailed = true;
                }
                result.addErrorDetails(
                    smh.getLocalString(
                        getClass().getName() + ".failed",
                        "Error: No alternate EJB deployment descriptor URI file found, looking for [ {0} ] within [ {1} ]",
                        new Object[] {
                          ejbd.getModuleDescriptor().getAlternateDescriptor(), ejbd.getName()
                        }));
              }
              // jarFile.close();

            } catch (FileNotFoundException ex) {
              Verifier.debug(ex);
              if (!oneFailed) {
                oneFailed = true;
              }

              result.failed(
                  smh.getLocalString(
                      getClass().getName() + ".failedException",
                      "Error: File not found trying to read deployment descriptor file [ {0} ] within [ {1} ]",
                      new Object[] {
                        ejbd.getModuleDescriptor().getAlternateDescriptor(), ejbd.getName()
                      }));
            } catch (IOException ex) {
              Verifier.debug(ex);
              if (!oneFailed) {
                oneFailed = true;
              }

              result.failed(
                  smh.getLocalString(
                      getClass().getName() + ".failedException1",
                      "Error: IO Error trying to read deployment descriptor file [ {0} ] within [ {1} ]",
                      new Object[] {
                        ejbd.getModuleDescriptor().getAlternateDescriptor(), ejbd.getName()
                      }));
            } finally {
              try {
                if (deploymentEntry != null) deploymentEntry.close();
              } catch (Exception x) {
              }
            }
          }
        } else {
          na++;
          result.notApplicable(
              smh.getLocalString(
                  getClass().getName() + ".notApplicable1",
                  "There is no java EJB alternative deployment descriptor in [ {0} ]",
                  new Object[] {ejbd.getName()}));
        }
      }
      if (oneFailed) {
        result.setStatus(Result.FAILED);
      } else if (na == descriptor.getEjbBundleDescriptors().size()) {
        result.setStatus(Result.NOT_APPLICABLE);
      } else {
        result.setStatus(Result.PASSED);
      }
    } else {
      result.notApplicable(
          smh.getLocalString(
              getClass().getName() + ".notApplicable",
              "There are no EJB components in application [ {0} ]",
              new Object[] {descriptor.getName()}));
    }

    return result;
  }
Esempio n. 18
0
  private boolean sendError(FacesContext context, String lifecycle, Exception e) {
    for (Throwable cause = e; cause != null; cause = cause.getCause()) {
      if (cause instanceof DisplayableException) {
        if (e instanceof RuntimeException) throw (RuntimeException) e;
        else throw new FacesException(e);
      } else if (cause instanceof ServletException) throw new FacesException(e);
      else if (cause instanceof JspException) throw new FacesException(e);
    }

    ExternalContext extContext = context.getExternalContext();
    Object response = extContext.getResponse();

    if (!(response instanceof HttpServletResponse)) {
      context.renderResponse();

      if (e instanceof RuntimeException) throw (RuntimeException) e;
      else throw new RuntimeException(e);
    }

    log.log(Level.WARNING, e.toString(), e);

    HttpServletResponse res = (HttpServletResponse) response;

    try {
      context.renderResponse();
      context.responseComplete();

      res.setStatus(500, "JSF Exception");
      res.setContentType("text/html");

      PrintWriter out = res.getWriter();

      out.println("<body>");

      out.println("<h3>JSF exception detected in " + lifecycle + " phase</h3>");

      String msg = e.getMessage();
      out.println("<span style='color:red;font:bold'>" + Html.escapeHtml(msg) + "</span><br/>");

      out.println("<h3>Context: " + context.getViewRoot() + "</h3>");
      out.println("<code><pre>");

      String errorId = null;

      if (e instanceof FacesException && msg.startsWith("id=")) {
        int p = msg.indexOf(' ');
        errorId = msg.substring(3, p);
      }

      printComponentTree(out, errorId, context, context.getViewRoot(), 0);

      out.println("</pre></code>");

      if (!Alarm.isTest()) {
        out.println("<h3>Stack Trace</h3>");
        out.println("<pre>");
        if (e.getCause() != null) e.getCause().printStackTrace(out);
        else e.printStackTrace(out);
        out.println("</pre>");
      }

      out.println("</body>");

      // clear, so we don't just loop
      Application app = context.getApplication();

      ViewHandler view = app.getViewHandler();

      UIViewRoot viewRoot = context.getViewRoot();

      viewRoot = view.createView(context, viewRoot.getViewId());

      context.setViewRoot(viewRoot);

      // view.writeState(context); // XXX: no need to output state, but review.

      return true;
    } catch (IOException e1) {
      throw new RuntimeException(e);
    }
  }
    public void runEvaluator() {
      int nSize = r.getNodeCount();
      nodeValues = new Double[nSize];
      allValues = new Double[nSize][];
      for (int i = 0; i < nSize; i++) {
        allValues[i] = new Double[nSize];
      }

      // get Oj's
      double[] o = new double[nSize];
      if (orgFile == null) {
        for (int i = 0; i < nSize; i++) {
          o[i] = 1.0;
        }
      } else {
        try {
          FileInputStream fis = new FileInputStream(orgFile);
          InputStreamReader isr = new InputStreamReader(fis);
          BufferedReader in = new BufferedReader(isr, 8096);
          String line = in.readLine();

          // try to guess delimiters
          String delim = " ";
          if (line.indexOf('\t') != 0) {
            delim = "\t";
          } else if (line.indexOf(',') != 0) {
            delim = ",";
          }
          Hashtable values = new Hashtable();
          while (line != null) {
            StringTokenizer st = new StringTokenizer(line, delim);
            line = in.readLine();
            String key = st.nextToken().trim();
            if (st.hasMoreTokens()) {
              try {
                Double d = Double.valueOf(st.nextToken());
                values.put(key, d);
              } catch (NumberFormatException nfe) {
                // ignore?
              }
            }
          }
          fis.close();
          TreeSet missingActors = new TreeSet();
          for (int i = 0; i < nSize; i++) {
            String actorName = r.getParent().getActor(i).getName();
            Double oValue = (Double) values.get(actorName);
            if (oValue == null) {
              missingActors.add(actorName);
              o[i] = 1.0;
            } else {
              o[i] = oValue.doubleValue();
            }
          }
          if (missingActors.size() > 0) {
            String errorMsg = "Couldn't find organization values for ";
            if (missingActors.size() <= 10) {
              Iterator iter = missingActors.iterator();
              errorMsg += "'" + iter.next() + "'";
              while (iter.hasNext()) {
                errorMsg += ", '" + iter.next() + "'";
              }
              errorMsg += ".";
            } else {
              errorMsg += missingActors.size() + " actors.";
            }
            JFrame f = new JFrame();
            JOptionPane.showMessageDialog(
                f, errorMsg, "Missing Values", JOptionPane.WARNING_MESSAGE);
          }
        } catch (IOException ioe) {
          Application.handleNonFatalThrowable(ioe);
        }
      }

      // i think i need to calculate all p_ij's
      double[][] p = new double[nSize][];
      for (int i = 0; i < nSize; i++) {
        p[i] = new double[nSize];
        double i_out = 0.0;
        for (int j = 0; j < nSize; j++) {
          if ((i != j) || (!ignoreDiagonals)) {
            if (investments == OUTBOUND || investments == BOTH) {
              i_out += r.getTieStrength(i, j);
            }
            if (investments == INBOUND || investments == BOTH) {
              i_out += r.getTieStrength(j, i);
            }
          }
        }

        for (int j = 0; j < nSize; j++) {
          p[i][j] = 0.0;
          if (i_out != 0.0) {
            if (investments == OUTBOUND || investments == BOTH) {
              p[i][j] += r.getTieStrength(i, j) / i_out;
            }
            if (investments == INBOUND || investments == BOTH) {
              p[i][j] += r.getTieStrength(j, i) / i_out;
            }
          }
        }
      }

      switch (type) {
          // implementation of Burt (1992: 64) equation 2.7
        case CONSTRAINT:
          for (int i = 0; i < nSize; i++) {
            double i_total = 0.0;
            allValues[i][i] = new Double(Double.NaN);
            for (int j = 0; j < nSize; j++) {
              if (i != j) {
                double c_sum = p[i][j];
                for (int q = 0; q < nSize; q++) {
                  if ((q != i) && (q != j)) {
                    c_sum += p[i][q] * p[q][j];
                  }
                }
                double c_ij = c_sum * c_sum * o[j];
                i_total += c_ij;
                allValues[i][j] = new Double(c_ij);
              }
            }
            nodeValues[i] = new Double(i_total);
          }
          break;

        case EFFECTIVE_SIZE:
          break;
      }
    }